Primitives are culled against the cull volume and then clipped to the clip volume. In clip coordinates, the view volume is defined by:
$ \begin{array}{c} -w_c \leq x_c \leq w_c \\ -w_c \leq y_c \leq w_c \\ 0 \leq z_c \leq w_c \\ \end{array} $
This view volume can be further restricted by as many as
VkPhysicalDeviceLimits
::maxClipDistances
client-defined
half-spaces.
The cull volume is the intersection of up to
VkPhysicalDeviceLimits
::maxCullDistances
client-defined
half-spaces (if no client-defined cull half-spaces are enabled, culling
against the cull volume is skipped).
A shader must write a single cull distance for each enabled cull half-space
to elements of the CullDistance
array.
If the cull distance for any enabled cull half-space is negative for all of
the vertices of the primitive under consideration, the primitive is
discarded.
Otherwise the primitive is clipped against the clip volume as defined below.
The clip volume is the intersection of up to
VkPhysicalDeviceLimits
::maxClipDistances
client-defined
half-spaces with the view volume (if no client-defined clip half-spaces are
enabled, the clip volume is the view volume).
A shader must write a single clip distance for each enabled clip half-space
to elements of the ClipDistance
array.
Clip half-space i is then given by the set of points satisfying the
inequality
where c_{i}(P) is the clip distance i at point P. For point primitives, c_{i}(P) is simply the clip distance for the vertex in question. For line and triangle primitives, per-vertex clip distances are interpolated using a weighted mean, with weights derived according to the algorithms described in sections Basic Line Segment Rasterization and Basic Polygon Rasterization, using the perspective interpolation equations.
The number of client-defined clip and cull half-spaces that are enabled is
determined by the explicit size of the built-in arrays ClipDistance
and
CullDistance
, respectively, declared as an output in the interface of
the entry point of the final shader stage before clipping.
Depth clamping is enabled or disabled via the depthClampEnable
enable
of the VkPipelineRasterizationStateCreateInfo
structure.
If depth clamping is enabled, the plane equation
(see the clip volume definition above) is ignored by view volume clipping (effectively, there is no near or far plane clipping).
If the primitive under consideration is a point, then clipping passes it unchanged if it lies within the clip volume; otherwise, it is discarded.
If the primitive is a line segment, then clipping does nothing to it if it lies entirely within the clip volume, and discards it if it lies entirely outside the volume.
If part of the line segment lies in the volume and part lies outside, then the line segment is clipped and new vertex coordinates are computed for one or both vertices. A clipped line segment endpoint lies on both the original line segment and the boundary of the clip volume.
This clipping produces a value, 0 ≤ t ≤ 1, for each clipped vertex. If the coordinates of a clipped vertex are P and the original vertices' coordinates are P_{1} and P_{2}, then t is given by
editing-note | |
---|---|
This is weird - it gives P, not t. |
t is used to clip vertex output attributes as described in Clipping Shader Outputs.
If the primitive is a polygon, it passes unchanged if every one of its edges lie entirely inside the clip volume, and it is discarded if every one of its edges lie entirely outside the clip volume. If the edges of the polygon intersect the boundary of the clip volume, the intersecting edges are reconnected by new edges that lie along the boundary of the clip volume - in some cases requiring the introduction of new vertices into a polygon.
If a polygon intersects an edge of the clip volume’s boundary, the clipped polygon must include a point on this boundary edge.
Primitives rendered with user-defined half-spaces must satisfy a complementarity criterion. Suppose a series of primitives is drawn where each vertex i has a single specified clip distance d_{i} (or a number of similarly specified clip distances, if multiple half-spaces are enabled). Next, suppose that the same series of primitives are drawn again with each such clip distance replaced by -d_{i} (and the graphics pipeline is otherwise the same). In this case, primitives must not be missing any pixels, and pixels must not be drawn twice in regions where those primitives are cut by the clip planes.