A line is drawn by generating a set of fragments overlapping a rectangle centered on the line segment. Each line segment has an associated width that controls the width of that rectangle.
The line width is set by the lineWidth
property of
VkPipelineRasterizationStateCreateInfo
in the currently active
pipeline if the pipeline was not created with
VK_DYNAMIC_STATE_LINE_WIDTH
enabled. Otherwise, the line width is set
by calling vkCmdSetLineWidth
:
void vkCmdSetLineWidth( VkCommandBuffer commandBuffer, float lineWidth);
commandBuffer
is the command buffer into which the command will be
recorded.
lineWidth
is the width of rasterized line segments.
Not all line widths need be supported for line segment rasterization, but
width 1.0 antialiased segments must be provided. The range and gradations
are obtained from the lineWidthRange
and lineWidthGranularity
members of VkPhysicalDeviceLimits
. If, for instance, the size range is
from 0.1 to 2.0 and the gradation size is 0.1, then the size 0.1, 0.2, …,
1.9, 2.0 are supported. Additional line widths may also be supported. There
is no requirement that these widths be equally spaced. If an unsupported
width is requested, the nearest supported width is used instead.
Rasterized line segments produce fragments which intersect a rectangle centered on the line segment. Two of the edges are parallel to the specified line segment; each is at a distance of one-half the current width from that segment in directions perpendicular to the direction of the line. The other two edges pass through the line endpoints and are perpendicular to the direction of the specified line segment. Coverage bits that correspond to sample points that intersect the rectangle are 1, other coverage bits are 0.
Next we specify how the data associated with each rasterized fragment
are obtained. Let
$\mathbf{p}_r = (x_d, y_d)$
be the
framebuffer coordinates at which associated data are evaluated. This may be
the pixel center of a fragment or the location of a sample within the
fragment. When rasterizationSamples
is VK_SAMPLE_COUNT_1_BIT
,
the pixel center must be used. Let
$\mathbf{p}_a = (x_a, y_a)$
and
$\mathbf{p}_b = (x_b,y_b)$
be initial and final endpoints of
the line segment, respectively. Set
(Note that $t=0$ at $\mathbf{p}_a$ and $t=1$ at $\mathbf{p}_b$ . Also note that this calculation projects the vector from $\mathbf{p}_a$ to $\mathbf{p}_r$ onto the line, and thus computes the normalized distance of the fragment along the line.)
The value of an associated datum $f$ for the fragment, whether it be a shader output or the clip $w$ coordinate, is found as
Equation 24.1. line_perspective_interpolation
where $f_a$ and $f_b$ are the data associated with the starting and ending endpoints of the segment, respectively; $w_a$ and $w_b$ are the clip $w$ coordinates of the starting and ending endpoints of the segments, respectively. However, depth values for lines must be interpolated by
where $z_a$ and $z_b$ are the depth values of the starting and ending endpoints of the segment, respectively.
The NoPerspective
and Flat
interpolation decorations can be used
with fragment shader inputs to declare how they are interpolated. When
neither decoration is applied, interpolation is performed as described in
Equation line_perspective_interpolation. When the NoPerspective
decoration
is used, interpolation is performed in the same fashion as for depth values,
as described in Equation line_noperspective_interpolation. When the Flat
decoration is used, no interpolation is performed, and outputs are taken
from the corresponding input value of the
provoking vertex corresponding to that
primitive.
The above description documents the preferred method of line rasterization,
and must be used when the implementation advertises the strictLines
limit in VkPhysicalDeviceLimits
as VK_TRUE
.
When strictLines
is VK_FALSE
, the edges of the lines are
generated as a parallelogram surrounding the original line. The major axis
is chosen by noting the axis in which there is the greatest distance between
the line start and end points. If the difference is equal in both directions
then the X axis is chosen as the major axis. Edges 2 and 3 are aligned to
the minor axis and are centered on the endpoints of the line as in
Figure 24.1, “Non strict lines”, and each is lineWidth
long. Edges 0 and 1
are parallel to the line and connect the endpoints of edges 2 and 3.
Coverage bits that correspond to sample points that intersect the
parallelogram are 1, other coverage bits are 0.
Samples that fall exactly on the edge of the parallelogram follow the polygon rasterization rules.
Interpolation occurs as if the parallelogram was decomposed into two triangles where each pair of vertices at each end of the line has identical attributes.