585 lines
27 KiB
Plaintext
585 lines
27 KiB
Plaintext
// Copyright (c) 2015-2018 Khronos Group. This work is licensed under a
|
|
// Creative Commons Attribution 4.0 International License; see
|
|
// http://creativecommons.org/licenses/by/4.0/
|
|
|
|
[[tessellation]]
|
|
= Tessellation
|
|
|
|
Tessellation involves three pipeline stages.
|
|
First, a <<shaders-tessellation-control,tessellation control shader>>
|
|
transforms control points of a patch and can: produce per-patch data.
|
|
Second, a fixed-function tessellator generates multiple primitives
|
|
corresponding to a tessellation of the patch in (u,v) or (u,v,w) parameter
|
|
space.
|
|
Third, a <<shaders-tessellation-evaluation,tessellation evaluation shader>>
|
|
transforms the vertices of the tessellated patch, for example to compute
|
|
their positions and attributes as part of the tessellated surface.
|
|
The tessellator is enabled when the pipeline contains both a tessellation
|
|
control shader and a tessellation evaluation shader.
|
|
|
|
|
|
== Tessellator
|
|
|
|
If a pipeline includes both tessellation shaders (control and evaluation),
|
|
the tessellator consumes each input patch (after vertex shading) and
|
|
produces a new set of independent primitives (points, lines, or triangles).
|
|
These primitives are logically produced by subdividing a geometric primitive
|
|
(rectangle or triangle) according to the per-patch outer and inner
|
|
tessellation levels written by the tessellation control shader.
|
|
These levels are specified using the <<interfaces-builtin-variables,built-in
|
|
variables>> code:TessLevelOuter and code:TessLevelInner, respectively.
|
|
This subdivision is performed in an implementation-dependent manner.
|
|
If no tessellation shaders are present in the pipeline, the tessellator is
|
|
disabled and incoming primitives are passed through without modification.
|
|
|
|
The type of subdivision performed by the tessellator is specified by an
|
|
code:OpExecutionMode instruction in the tessellation evaluation or
|
|
tessellation control shader using one of execution modes code:Triangles,
|
|
code:Quads, and code:IsoLines.
|
|
Other tessellation-related execution modes can: also be specified in either
|
|
the tessellation control or tessellation evaluation shaders, and if they are
|
|
specified in both then the modes must: be the same.
|
|
|
|
Tessellation execution modes include:
|
|
|
|
* code:Triangles, code:Quads, and code:IsoLines.
|
|
These control the type of subdivision and topology of the output
|
|
primitives.
|
|
One mode must: be set in at least one of the tessellation shader stages.
|
|
* code:VertexOrderCw and code:VertexOrderCcw.
|
|
These control the orientation of triangles generated by the tessellator.
|
|
One mode must: be set in at least one of the tessellation shader stages.
|
|
* code:PointMode.
|
|
Controls generation of points rather than triangles or lines.
|
|
This functionality defaults to disabled, and is enabled if either shader
|
|
stage includes the execution mode.
|
|
* code:SpacingEqual, code:SpacingFractionalEven, and
|
|
code:SpacingFractionalOdd.
|
|
Controls the spacing of segments on the edges of tessellated primitives.
|
|
One mode must: be set in at least one of the tessellation shader stages.
|
|
* code:OutputVertices.
|
|
Controls the size of the output patch of the tessellation control
|
|
shader.
|
|
One value must: be set in at least one of the tessellation shader
|
|
stages.
|
|
|
|
For triangles, the tessellator subdivides a triangle primitive into smaller
|
|
triangles.
|
|
For quads, the tessellator subdivides a rectangle primitive into smaller
|
|
triangles.
|
|
For isolines, the tessellator subdivides a rectangle primitive into a
|
|
collection of line segments arranged in strips stretching across the
|
|
rectangle in the [eq]#u# dimension (i.e. the coordinates in code:TessCoord
|
|
are of the form (0,x) through (1,x) for all tessellation evaluation shader
|
|
invocations that share a line).
|
|
|
|
Each vertex produced by the tessellator has an associated (u,v,w) or (u,v)
|
|
position in a normalized parameter space, with parameter values in the range
|
|
[eq]#[0,1]#, as illustrated
|
|
ifdef::VK_VERSION_1_1,VK_KHR_maintenance2[]
|
|
in figures <<img-tessellation-topology-ul>> and
|
|
<<img-tessellation-topology-ll>>.
|
|
The domain space can: have either an upper-left or lower-left origin,
|
|
selected by the pname:domainOrigin member of
|
|
slink:VkPipelineTessellationDomainOriginStateCreateInfo.
|
|
endif::VK_VERSION_1_1,VK_KHR_maintenance2[]
|
|
ifndef::VK_VERSION_1_1,VK_KHR_maintenance2[]
|
|
in figure <<img-tessellation-topology-ul>>.
|
|
The domain space has an upper-left origin.
|
|
endif::VK_VERSION_1_1,VK_KHR_maintenance2[]
|
|
|
|
[[img-tessellation-topology-ul]]
|
|
image::images/tessparamUL.svg[align="center",title="Domain parameterization for tessellation primitive modes (upper-left origin)",opts="{imageopts}"]
|
|
|
|
ifdef::VK_VERSION_1_1,VK_KHR_maintenance2[]
|
|
[[img-tessellation-topology-ll]]
|
|
image::images/tessparam.svg[align="center",title="Domain parameterization for tessellation primitive modes (lower-left origin)",opts="{imageopts}"]
|
|
endif::VK_VERSION_1_1,VK_KHR_maintenance2[]
|
|
|
|
.Caption
|
|
****
|
|
In the domain parameterization diagrams, the coordinates illustrate the
|
|
value of code:TessCoord at the corners of the domain.
|
|
The labels on the edges indicate the inner (IL0 and IL1) and outer (OL0
|
|
through OL3) tessellation level values used to control the number of
|
|
subdivisions along each edge of the domain.
|
|
****
|
|
|
|
For triangles, the vertex's position is a barycentric coordinate
|
|
[eq]#(u,v,w)#, where [eq]#u {plus} v {plus} w = 1.0#, and indicates the
|
|
relative influence of the three vertices of the triangle on the position of
|
|
the vertex.
|
|
For quads and isolines, the position is a [eq]#(u,v)# coordinate indicating
|
|
the relative horizontal and vertical position of the vertex relative to the
|
|
subdivided rectangle.
|
|
The subdivision process is explained in more detail in subsequent sections.
|
|
|
|
|
|
== Tessellator Patch Discard
|
|
|
|
A patch is discarded by the tessellator if any relevant outer tessellation
|
|
level is less than or equal to zero.
|
|
|
|
Patches will also be discarded if any relevant outer tessellation level
|
|
corresponds to a floating-point [eq]#NaN# (not a number) in implementations
|
|
supporting [eq]#NaN#.
|
|
|
|
No new primitives are generated and the tessellation evaluation shader is
|
|
not executed for patches that are discarded.
|
|
For code:Quads, all four outer levels are relevant.
|
|
For code:Triangles and code:IsoLines, only the first three or two outer
|
|
levels, respectively, are relevant.
|
|
Negative inner levels will not cause a patch to be discarded; they will be
|
|
clamped as described below.
|
|
|
|
|
|
[[tessellation-tessellator-spacing]]
|
|
== Tessellator Spacing
|
|
|
|
Each of the tessellation levels is used to determine the number and spacing
|
|
of segments used to subdivide a corresponding edge.
|
|
The method used to derive the number and spacing of segments is specified by
|
|
an code:OpExecutionMode in the tessellation control or tessellation
|
|
evaluation shader using one of the identifiers code:SpacingEqual,
|
|
code:SpacingFractionalEven, or code:SpacingFractionalOdd.
|
|
|
|
If code:SpacingEqual is used, the floating-point tessellation level is first
|
|
clamped to [eq]#[1, pname:maxLevel]#, where [eq]#pname:maxLevel# is the
|
|
implementation-dependent maximum tessellation level
|
|
(sname:VkPhysicalDeviceLimits::pname:maxTessellationGenerationLevel).
|
|
The result is rounded up to the nearest integer [eq]#n#, and the
|
|
corresponding edge is divided into [eq]#n# segments of equal length in (u,v)
|
|
space.
|
|
|
|
If code:SpacingFractionalEven is used, the tessellation level is first
|
|
clamped to [eq]#[2, pname:maxLevel]# and then rounded up to the nearest even
|
|
integer [eq]#n#.
|
|
If code:SpacingFractionalOdd is used, the tessellation level is clamped to
|
|
[eq]#[1, pname:maxLevel - 1]# and then rounded up to the nearest odd integer
|
|
[eq]#n#.
|
|
If [eq]#n# is one, the edge will not be subdivided.
|
|
Otherwise, the corresponding edge will be divided into [eq]#n - 2# segments
|
|
of equal length, and two additional segments of equal length that are
|
|
typically shorter than the other segments.
|
|
The length of the two additional segments relative to the others will
|
|
decrease monotonically with [eq]#n - f#, where [eq]#f# is the clamped
|
|
floating-point tessellation level.
|
|
When [eq]#n - f# is zero, the additional segments will have equal length to
|
|
the other segments.
|
|
As [eq]#n - f# approaches 2.0, the relative length of the additional
|
|
segments approaches zero.
|
|
The two additional segments must: be placed symmetrically on opposite sides
|
|
of the subdivided edge.
|
|
The relative location of these two segments is implementation-dependent, but
|
|
must: be identical for any pair of subdivided edges with identical values of
|
|
[eq]#f#.
|
|
|
|
When the tessellator produces triangles (in the code:Triangles or code:Quads
|
|
modes), the orientation of all triangles is specified with an
|
|
code:OpExecutionMode of code:VertexOrderCw or code:VertexOrderCcw in the
|
|
tessellation control or tessellation evaluation shaders.
|
|
If the order is code:VertexOrderCw, the vertices of all generated triangles
|
|
will have clockwise ordering in (u,v) or (u,v,w) space.
|
|
If the order is code:VertexOrderCcw, the vertices will have
|
|
counter-clockwise ordering.
|
|
|
|
If the tessellation domain has an upper-left origin, the vertices of a
|
|
triangle have counter-clockwise ordering if
|
|
|
|
:: [eq]#a = u~0~ v~1~ - u~1~ v~0~ {plus} u~1~ v~2~ - u~2~ v~1~ {plus} u~2~
|
|
v~0~ - u~0~ v~2~#
|
|
|
|
is negative, and clockwise ordering if [eq]#a# is positive.
|
|
[eq]#u~i~# and [eq]#v~i~# are the [eq]#u# and [eq]#v# coordinates in
|
|
normalized parameter space of the [eq]##i##th vertex of the triangle.
|
|
ifdef::VK_VERSION_1_1,VK_KHR_maintenance2[]
|
|
If the tessellation domain has a lower-left origin, the vertices of a
|
|
triangle have counter-clockwise ordering if [eq]#a# is positive, and
|
|
clockwise ordering if [eq]#a# is negative.
|
|
endif::VK_VERSION_1_1,VK_KHR_maintenance2[]
|
|
|
|
[NOTE]
|
|
.Note
|
|
====
|
|
The value [eq]#a# is proportional (with a positive factor) to the signed
|
|
area of the triangle.
|
|
|
|
In code:Triangles mode, even though the vertex coordinates have a [eq]#w#
|
|
value, it does not participate directly in the computation of [eq]#a#, being
|
|
an affine combination of [eq]#u# and [eq]#v#.
|
|
====
|
|
|
|
For all primitive modes, the tessellator is capable of generating points
|
|
instead of lines or triangles.
|
|
If the tessellation control or tessellation evaluation shader specifies the
|
|
code:OpExecutionMode code:PointMode, the primitive generator will generate
|
|
one point for each distinct vertex produced by tessellation.
|
|
Otherwise, the tessellator will produce a collection of line segments or
|
|
triangles according to the primitive mode.
|
|
When tessellating triangles or quads in point mode with fractional odd
|
|
spacing, the tessellator may: produce _interior vertices_ that are
|
|
positioned on the edge of the patch if an inner tessellation level is less
|
|
than or equal to one.
|
|
Such vertices are considered distinct from vertices produced by subdividing
|
|
the outer edge of the patch, even if there are pairs of vertices with
|
|
identical coordinates.
|
|
|
|
|
|
[[tessellation-primitive-order]]
|
|
== Tessellation Primitive Ordering
|
|
|
|
Few guarantees are provided for the relative ordering of primitives produced
|
|
by tessellation, as they pertain to <<drawing-primitive-order, primitive
|
|
order>>.
|
|
|
|
* The output primitives generated from each input primitive are passed to
|
|
subsequent pipeline stages in an implementation-dependent order.
|
|
* All output primitives generated from a given input primitive are passed
|
|
to subsequent pipeline stages before any output primitives generated
|
|
from subsequent input primitives.
|
|
|
|
|
|
[[tessellation-triangle-tessellation]]
|
|
== Triangle Tessellation
|
|
|
|
If the tessellation primitive mode is code:Triangles, an equilateral
|
|
triangle is subdivided into a collection of triangles covering the area of
|
|
the original triangle.
|
|
First, the original triangle is subdivided into a collection of concentric
|
|
equilateral triangles.
|
|
The edges of each of these triangles are subdivided, and the area between
|
|
each triangle pair is filled by triangles produced by joining the vertices
|
|
on the subdivided edges.
|
|
The number of concentric triangles and the number of subdivisions along each
|
|
triangle except the outermost is derived from the first inner tessellation
|
|
level.
|
|
The edges of the outermost triangle are subdivided independently, using the
|
|
first, second, and third outer tessellation levels to control the number of
|
|
subdivisions of the [eq]#u = 0# (left), [eq]#v = 0# (bottom), and [eq]#w =
|
|
0# (right) edges, respectively.
|
|
The second inner tessellation level and the fourth outer tessellation level
|
|
have no effect in this mode.
|
|
|
|
If the first inner tessellation level and all three outer tessellation
|
|
levels are exactly one after clamping and rounding, only a single triangle
|
|
with [eq]#(u,v,w)# coordinates of [eq]#(0,0,1)#, [eq]#(1,0,0)#, and
|
|
[eq]#(0,1,0)# is generated.
|
|
If the inner tessellation level is one and any of the outer tessellation
|
|
levels is greater than one, the inner tessellation level is treated as
|
|
though it were originally specified as [eq]#1 {plus} {epsilon}# and will
|
|
result in a two- or three-segment subdivision depending on the tessellation
|
|
spacing.
|
|
When used with fractional odd spacing, the three-segment subdivision may:
|
|
produce _inner vertices_ positioned on the edge of the triangle.
|
|
|
|
If any tessellation level is greater than one, tessellation begins by
|
|
producing a set of concentric inner triangles and subdividing their edges.
|
|
First, the three outer edges are temporarily subdivided using the clamped
|
|
and rounded first inner tessellation level and the specified tessellation
|
|
spacing, generating [eq]#n# segments.
|
|
For the outermost inner triangle, the inner triangle is degenerate -- a
|
|
single point at the center of the triangle -- if [eq]#n# is two.
|
|
Otherwise, for each corner of the outer triangle, an inner triangle corner
|
|
is produced at the intersection of two lines extended perpendicular to the
|
|
corner's two adjacent edges running through the vertex of the subdivided
|
|
outer edge nearest that corner.
|
|
If [eq]#n# is three, the edges of the inner triangle are not subdivided and
|
|
is the final triangle in the set of concentric triangles.
|
|
Otherwise, each edge of the inner triangle is divided into [eq]#n - 2#
|
|
segments, with the [eq]#n - 1# vertices of this subdivision produced by
|
|
intersecting the inner edge with lines perpendicular to the edge running
|
|
through the [eq]#n - 1# innermost vertices of the subdivision of the outer
|
|
edge.
|
|
Once the outermost inner triangle is subdivided, the previous subdivision
|
|
process repeats itself, using the generated triangle as an outer triangle.
|
|
This subdivision process is illustrated in <<img-innertri,Inner Triangle
|
|
Tessellation>>.
|
|
|
|
[[img-innertri]]
|
|
image::images/innertri.svg[align="center",title="Inner Triangle Tessellation",opts="{imageopts}"]
|
|
|
|
.Caption
|
|
****
|
|
In the <<img-innertri,Inner Triangle Tessellation>> diagram, inner
|
|
tessellation levels of (a) five and (b) four are shown (not to scale).
|
|
Solid black circles depict vertices along the edges of the concentric
|
|
triangles.
|
|
The edges of inner triangles are subdivided by intersecting the edge with
|
|
segments perpendicular to the edge passing through each inner vertex of the
|
|
subdivided outer edge.
|
|
Dotted lines depict edges connecting corresponding vertices on the inner and
|
|
outer triangle edges.
|
|
****
|
|
|
|
Once all the concentric triangles are produced and their edges are
|
|
subdivided, the area between each pair of adjacent inner triangles is filled
|
|
completely with a set of non-overlapping triangles.
|
|
In this subdivision, two of the three vertices of each triangle are taken
|
|
from adjacent vertices on a subdivided edge of one triangle; the third is
|
|
one of the vertices on the corresponding edge of the other triangle.
|
|
If the innermost triangle is degenerate (i.e., a point), the triangle
|
|
containing it is subdivided into six triangles by connecting each of the six
|
|
vertices on that triangle with the center point.
|
|
If the innermost triangle is not degenerate, that triangle is added to the
|
|
set of generated triangles as-is.
|
|
|
|
After the area corresponding to any inner triangles is filled, the
|
|
tessellator generates triangles to cover the area between the outermost
|
|
triangle and the outermost inner triangle.
|
|
To do this, the temporary subdivision of the outer triangle edge above is
|
|
discarded.
|
|
Instead, the [eq]#u = 0#, [eq]#v = 0#, and [eq]#w = 0# edges are subdivided
|
|
according to the first, second, and third outer tessellation levels,
|
|
respectively, and the tessellation spacing.
|
|
The original subdivision of the first inner triangle is retained.
|
|
The area between the outer and first inner triangles is completely filled by
|
|
non-overlapping triangles as described above.
|
|
If the first (and only) inner triangle is degenerate, a set of triangles is
|
|
produced by connecting each vertex on the outer triangle edges with the
|
|
center point.
|
|
|
|
After all triangles are generated, each vertex in the subdivided triangle is
|
|
assigned a barycentric (u,v,w) coordinate based on its location relative to
|
|
the three vertices of the outer triangle.
|
|
|
|
The algorithm used to subdivide the triangular domain in (u,v,w) space into
|
|
individual triangles is implementation-dependent.
|
|
However, the set of triangles produced will completely cover the domain, and
|
|
no portion of the domain will be covered by multiple triangles.
|
|
|
|
The order in which the vertices for a given output triangle is generated is
|
|
implementation-dependent.
|
|
However, when depicted in a manner similar to <<img-innertri,Inner Triangle
|
|
Tessellation>>, the order of the vertices in each generated triangle will be
|
|
either all clockwise or all counter-clockwise, according to the vertex order
|
|
layout declaration.
|
|
|
|
|
|
[[tessellation-quad-tessellation]]
|
|
== Quad Tessellation
|
|
|
|
If the tessellation primitive mode is code:Quads, a rectangle is subdivided
|
|
into a collection of triangles covering the area of the original rectangle.
|
|
First, the original rectangle is subdivided into a regular mesh of
|
|
rectangles, where the number of rectangles along the [eq]#u = 0# and [eq]#u
|
|
= 1# (vertical) and [eq]#v = 0# and [eq]#v = 1# (horizontal) edges are
|
|
derived from the first and second inner tessellation levels, respectively.
|
|
All rectangles, except those adjacent to one of the outer rectangle edges,
|
|
are decomposed into triangle pairs.
|
|
The outermost rectangle edges are subdivided independently, using the first,
|
|
second, third, and fourth outer tessellation levels to control the number of
|
|
subdivisions of the [eq]#u = 0# (left), [eq]#v = 0# (bottom), [eq]#u = 1#
|
|
(right), and [eq]#v = 1# (top) edges, respectively.
|
|
The area between the inner rectangles of the mesh and the outer rectangle
|
|
edges are filled by triangles produced by joining the vertices on the
|
|
subdivided outer edges to the vertices on the edge of the inner rectangle
|
|
mesh.
|
|
|
|
If both clamped inner tessellation levels and all four clamped outer
|
|
tessellation levels are exactly one, only a single triangle pair covering
|
|
the outer rectangle is generated.
|
|
Otherwise, if either clamped inner tessellation level is one, that
|
|
tessellation level is treated as though it were originally specified as
|
|
[eq]#1 {plus} {epsilon}# and will result in a two- or three-segment
|
|
subdivision depending on the tessellation spacing.
|
|
When used with fractional odd spacing, the three-segment subdivision may:
|
|
produce _inner vertices_ positioned on the edge of the rectangle.
|
|
|
|
If any tessellation level is greater than one, tessellation begins by
|
|
subdividing the [eq]#u = 0# and [eq]#u = 1# edges of the outer rectangle
|
|
into [eq]#m# segments using the clamped and rounded first inner tessellation
|
|
level and the tessellation spacing.
|
|
The [eq]#v = 0# and [eq]#v = 1# edges are subdivided into [eq]#n# segments
|
|
using the second inner tessellation level.
|
|
Each vertex on the [eq]#u = 0# and [eq]#v = 0# edges are joined with the
|
|
corresponding vertex on the [eq]#u = 1# and [eq]#v = 1# edges to produce a
|
|
set of vertical and horizontal lines that divide the rectangle into a grid
|
|
of smaller rectangles.
|
|
The primitive generator emits a pair of non-overlapping triangles covering
|
|
each such rectangle not adjacent to an edge of the outer rectangle.
|
|
The boundary of the region covered by these triangles forms an inner
|
|
rectangle, the edges of which are subdivided by the grid vertices that lie
|
|
on the edge.
|
|
If either [eq]#m# or [eq]#n# is two, the inner rectangle is degenerate, and
|
|
one or both of the rectangle's _edges_ consist of a single point.
|
|
This subdivision is illustrated in Figure <<img-innerquad,Inner Quad
|
|
Tessellation>>.
|
|
|
|
[[img-innerquad]]
|
|
image::images/innerquad.svg[align="center",title="Inner Quad Tessellation",opts="{imageopts}"]
|
|
|
|
.Caption
|
|
****
|
|
In the <<img-innerquad,Inner Quad Tessellation>> diagram, inner quad
|
|
tessellation levels of (a) [eq]#(4,2)# and (b) [eq]#(7,4)# are shown.
|
|
The regions highlighted in red in figure (b) depict the 10 inner rectangles,
|
|
each of which will be subdivided into two triangles.
|
|
Solid black circles depict vertices on the boundary of the outer and inner
|
|
rectangles, where the inner rectangle on the top figure is degenerate (a
|
|
single line segment).
|
|
Dotted lines depict the horizontal and vertical edges connecting
|
|
corresponding vertices on the inner and outer rectangle edges.
|
|
****
|
|
|
|
After the area corresponding to the inner rectangle is filled, the
|
|
tessellator must: produce triangles to cover the area between the inner and
|
|
outer rectangles.
|
|
To do this, the subdivision of the outer rectangle edge above is discarded.
|
|
Instead, the [eq]#u = 0#, [eq]#v = 0#, [eq]#u = 1#, and [eq]#v = 1# edges
|
|
are subdivided according to the first, second, third, and fourth outer
|
|
tessellation levels, respectively, and the tessellation spacing.
|
|
The original subdivision of the inner rectangle is retained.
|
|
The area between the outer and inner rectangles is completely filled by
|
|
non-overlapping triangles.
|
|
Two of the three vertices of each triangle are adjacent vertices on a
|
|
subdivided edge of one rectangle; the third is one of the vertices on the
|
|
corresponding edge of the other triangle.
|
|
If either edge of the innermost rectangle is degenerate, the area near the
|
|
corresponding outer edges is filled by connecting each vertex on the outer
|
|
edge with the single vertex making up the _inner edge_.
|
|
|
|
The algorithm used to subdivide the rectangular domain in (u,v) space into
|
|
individual triangles is implementation-dependent.
|
|
However, the set of triangles produced will completely cover the domain, and
|
|
no portion of the domain will be covered by multiple triangles.
|
|
|
|
The order in which the vertices for a given output triangle is generated is
|
|
implementation-dependent.
|
|
However, when depicted in a manner similar to <<img-innerquad,Inner Quad
|
|
Tessellation>>, the order of the vertices in each generated triangle will be
|
|
either all clockwise or all counter-clockwise, according to the vertex order
|
|
layout declaration.
|
|
|
|
|
|
[[tessellation-isoline-tessellation]]
|
|
== Isoline Tessellation
|
|
|
|
If the tessellation primitive mode is code:IsoLines, a set of independent
|
|
horizontal line segments is drawn.
|
|
The segments are arranged into connected strips called _isolines_, where the
|
|
vertices of each isoline have a constant v coordinate and u coordinates
|
|
covering the full range [eq]#[0,1]#.
|
|
The number of isolines generated is derived from the first outer
|
|
tessellation level; the number of segments in each isoline is derived from
|
|
the second outer tessellation level.
|
|
Both inner tessellation levels and the third and fourth outer tessellation
|
|
levels have no effect in this mode.
|
|
|
|
As with quad tessellation above, isoline tessellation begins with a
|
|
rectangle.
|
|
The [eq]#u = 0# and [eq]#u = 1# edges of the rectangle are subdivided
|
|
according to the first outer tessellation level.
|
|
For the purposes of this subdivision, the tessellation spacing mode is
|
|
ignored and treated as equal_spacing.
|
|
An isoline is drawn connecting each vertex on the [eq]#u = 0# rectangle edge
|
|
to the corresponding vertex on the [eq]#u = 1# rectangle edge, except that
|
|
no line is drawn between (0,1) and (1,1).
|
|
If the number of isolines on the subdivided [eq]#u = 0# and [eq]#u = 1#
|
|
edges is [eq]#n#, this process will result in [eq]#n# equally spaced lines
|
|
with constant v coordinates of 0, latexmath:[\frac{1}{n}, \frac{2}{n},
|
|
\ldots, \frac{n-1}{n}].
|
|
|
|
Each of the [eq]#n# isolines is then subdivided according to the second
|
|
outer tessellation level and the tessellation spacing, resulting in [eq]#m#
|
|
line segments.
|
|
Each segment of each line is emitted by the tessellator.
|
|
|
|
The order in which the vertices for a given output line is generated is
|
|
implementation-dependent.
|
|
|
|
|
|
== Tessellation Pipeline State
|
|
|
|
The pname:pTessellationState member of slink:VkGraphicsPipelineCreateInfo
|
|
points to a structure of type sname:VkPipelineTessellationStateCreateInfo.
|
|
|
|
[open,refpage='VkPipelineTessellationStateCreateInfo',desc='Structure specifying parameters of a newly created pipeline tessellation state',type='structs']
|
|
--
|
|
|
|
The sname:VkPipelineTessellationStateCreateInfo structure is defined as:
|
|
|
|
include::../api/structs/VkPipelineTessellationStateCreateInfo.txt[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
|
|
* pname:flags is reserved for future use.
|
|
* pname:patchControlPoints number of control points per patch.
|
|
|
|
.Valid Usage
|
|
****
|
|
* [[VUID-VkPipelineTessellationStateCreateInfo-patchControlPoints-01214]]
|
|
pname:patchControlPoints must: be greater than zero and less than or
|
|
equal to sname:VkPhysicalDeviceLimits::pname:maxTessellationPatchSize
|
|
****
|
|
|
|
include::../validity/structs/VkPipelineTessellationStateCreateInfo.txt[]
|
|
--
|
|
|
|
[open,refpage='VkPipelineTessellationStateCreateFlags',desc='Reserved for future use',type='enums']
|
|
--
|
|
include::../api/flags/VkPipelineTessellationStateCreateFlags.txt[]
|
|
|
|
sname:VkPipelineTessellationStateCreateFlags is a bitmask type for setting a
|
|
mask, but is currently reserved for future use.
|
|
--
|
|
|
|
ifdef::VK_VERSION_1_1,VK_KHR_maintenance2[]
|
|
|
|
[open,refpage='VkPipelineTessellationDomainOriginStateCreateInfo',desc='Structure specifying the orientation of the tessellation domain',type='structs']
|
|
--
|
|
|
|
The sname:VkPipelineTessellationDomainOriginStateCreateInfo structure is
|
|
defined as:
|
|
|
|
include::../api/structs/VkPipelineTessellationDomainOriginStateCreateInfo.txt[]
|
|
|
|
ifdef::VK_KHR_maintenance2[]
|
|
or the equivalent
|
|
|
|
include::../api/structs/VkPipelineTessellationDomainOriginStateCreateInfoKHR.txt[]
|
|
endif::VK_KHR_maintenance2[]
|
|
|
|
* pname:sType is the type of this structure.
|
|
* pname:pNext is `NULL` or a pointer to an extension-specific structure.
|
|
* pname:domainOrigin controls the origin of the tessellation domain space,
|
|
and is of type elink:VkTessellationDomainOrigin.
|
|
|
|
If the sname:VkPipelineTessellationDomainOriginStateCreateInfo structure is
|
|
included in the pname:pNext chain of
|
|
slink:VkPipelineTessellationStateCreateInfo, it controls the origin of the
|
|
tessellation domain.
|
|
If this structure is not present, it is as if pname:domainOrigin were
|
|
ename:VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT.
|
|
|
|
include::../validity/structs/VkPipelineTessellationDomainOriginStateCreateInfo.txt[]
|
|
--
|
|
|
|
[open,refpage='VkTessellationDomainOrigin',desc='Enum describing tessellation domain origin',type='enums']
|
|
--
|
|
|
|
The possible tessellation domain origins are specified by the
|
|
elink:VkTessellationDomainOrigin enumeration:
|
|
|
|
include::../api/enums/VkTessellationDomainOrigin.txt[]
|
|
|
|
ifdef::VK_KHR_maintenance2[]
|
|
or the equivalent
|
|
|
|
include::../api/enums/VkTessellationDomainOriginKHR.txt[]
|
|
endif::VK_KHR_maintenance2[]
|
|
|
|
* ename:VK_TESSELLATION_DOMAIN_ORIGIN_UPPER_LEFT specifies that the origin
|
|
of the domain space is in the upper left corner, as shown in figure
|
|
<<img-tessellation-topology-ul>>.
|
|
* ename:VK_TESSELLATION_DOMAIN_ORIGIN_LOWER_LEFT specifies that the origin
|
|
of the domain space is in the lower left corner, as shown in figure
|
|
<<img-tessellation-topology-ll>>.
|
|
|
|
This enum affects how the code:VertexOrderCw and code:VertexOrderCcw
|
|
tessellation execution modes are interpreted, since the winding is defined
|
|
relative to the orientation of the domain.
|
|
|
|
--
|
|
|
|
endif::VK_VERSION_1_1,VK_KHR_maintenance2[]
|