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 pr = (xd, yd) 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 pa = (xa, ya) and pb = (xb,yb) be
initial and final endpoints of the line segment, respectively.
Set
(Note that t = 0 at p_a and t = 1 at pb. Also note that this calculation projects the vector from pa to pr 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, must be determined using perspective interpolation:
where fa and fb are the data associated with the starting and ending endpoints of the segment, respectively; wa and wb are the clip w coordinates of the starting and ending endpoints of the segments, respectively.
Depth values for lines must be determined using linear interpolation:
where za and zb 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, perspective interpolation is performed as described above.
When the NoPerspective
decoration is used, linear interpolation is performed in the same fashion as for depth values,
as described above.
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.