A polygon results from the decomposition of a triangle strip, triangle fan or a series of independent triangles. Like points and line segments, polygon rasterization is controlled by several variables in the afxPipelineRasterizationConfig structure.

## Basic Polygon Rasterization

The first step of polygon rasterization is to determine whether the triangle is back-facing or frontfacing. This determination is made based on the sign of the (clipped or unclipped) polygon’s area computed in framebuffer coordinates. One way to compute this area is:

a = [formula pendente]

where and are the x and y framebuffer coordinates of the ith vertex of the n-vertex polygon (vertices are numbered starting at zero for the purposes of this computation) and i ⊕ 1 is (i + 1) mod n.

The interpretation of the sign of a is determined by the cwFrontFacing property of the currently active pipeline.

Any triangle which is not front-facing is back-facing, including zero-area triangles.

To dynamically set the front face orientation, call:

```
void AfxCmdSetFrontFace
(
afxDrawScript dscr, /// is the command buffer into which the command will be recorded.
afxBool cw /// is a value specifying the front-facing triangle orientation to be used for
culling.
);
```

This command sets the front face orientation for subsequent drawing commands when the graphics pipeline is created with VK_DYNAMIC_STATE_FRONT_FACE set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the VkPipelineRasterizationStateCreateInfo::frontFace value used to create the currently active pipeline.

Once the orientation of triangles is determined, they are culled according to the cullMode property of the currently active pipeline. Possible values are:

```
typedef enum afxCullMode
{
/// NIL specifies that no triangles are discarded.
afxCullMode_FRONT = AFX_FLAG(0), /// specifies that front-facing triangles are discarded.
afxCullMode_BACK = AFX_FLAG(1), /// specifies that back-facing triangles are discarded.
afxCullMode_BOTH = afxCullMode_FRONT | afxCullMode_BACK,
} afxCullMode;
```

afxCullMode is a bitmask type for setting a mask of zero or more faces.

Following culling, fragments are produced for any triangles which have not been discarded.

To dynamically set the cull mode, call:

```
void AfxCmdSetCullMode
(
afxDrawScript dscr, /// is the command buffer into which the command will be recorded.
afxCullMode mode /// specifies the cull mode property to use for drawing.
);
```

This command sets the cull mode for subsequent drawing commands when the graphics pipeline is created with VK_DYNAMIC_STATE_CULL_MODE set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the VkPipelineRasterizationStateCreateInfo::cullMode value used to create the currently active pipeline.

The rule for determining which fragments are produced by polygon rasterization is called point sampling. The two-dimensional projection obtained by taking the x and y framebuffer coordinates of the polygon’s vertices is formed. Fragments are produced for any fragment area groups of pixels for which any sample points lie inside of this polygon. Coverage bits that correspond to sample points that satisfy the point sampling criteria are 1, other coverage bits are 0. Special treatment is given to a sample whose sample location lies on a polygon edge. In such a case, if two polygons lie on either side of a common edge (with identical endpoints) on which a sample point lies, then exactly one of the polygons must result in a covered sample for that fragment during rasterization. As for the data associated with each fragment produced by rasterizing a polygon, we begin by specifying how these values are produced for fragments in a triangle.

Barycentric coordinates are a set of three numbers, a, b, and c, each in the range [0,1], with a + b + c = 1. These coordinates uniquely specify any point p within the triangle or on the triangle’s boundary as

p = a * pa b * pb + c * pc

where pa, pb, and pc are the vertices of the triangle. a, b, and c are determined by:

a = (A * (p * pb * pc)) / (A * (pa * pb * pc)),

b = (A * (p * pa * pc)) / (A * (pa * pb * pc)),

c = (A * (p * pa * pb)) / (A * (pa * pb * pc)),

where A(lmn) denotes the area in framebuffer coordinates of the triangle with vertices l, m, and n.

Denote an associated datum at pa, pb, or pc as fa, fb, or fc, respectively.

Perspective interpolation for a triangle interpolates three values in a manner that is correct when taking the perspective of the viewport into consideration, by way of the triangle’s clip coordinates. An interpolated value f can be determined by

f = (a * fa / wa + b * fb / wb + c * fc / wc) / (a / wa + b / wb + c /wc)

where wa, wb, and wc are the clip w coordinates of pa, pb, and pc, respectively. a, b, and c are the barycentric coordinates of the location at which the data are produced.

Linear interpolation for a triangle directly interpolates three values, and an interpolated value f can be determined by

f = a * fa + b * fb + c * fc

where fa, fb, and fc are the data associated with pa, pb, and pc, respectively.

The clip coordinate w for a sample is determined using perspective interpolation. The depth value z for a sample is determined using linear interpolation. Interpolation of fragment shader input values are determined by Interpolation decorations.

For a polygon with more than three edges, such as are produced by clipping a triangle, a convex combination of the values of the datum at the polygon’s vertices must be used to obtain the value assigned to each fragment produced by the rasterization algorithm. That is, it must be the case that at every fragment

[formula]

Note

One algorithm that achieves the required behavior is to triangulate a polygon (without adding any vertices) and then treat each triangle individually as already discussed. A scan-line rasterizer that linearly interpolates data along each edge and then linearly interpolates data across each horizontal span from edge to edge also satisfies the restrictions (in this case the numerator and denominator of perspective interpolation are iterated independently, and a division is performed for each fragment).

## Polygon Mode

Possible values of the fillMode property of the currently active pipeline, specifying the method of rasterization for polygons, are:

```
typedef enum afxFillMode
{
afxFillMode_FILL, /// specifies that polygons are rendered using the polygon rasterization rules
in this section.
afxFillMode_LINE, /// specifies that polygon edges are drawn as line segments.
afxFillMode_POINT, /// specifies that polygon vertices are drawn as points.
} afxFillMode;
```

These modes affect only the final rasterization of polygons: in particular, a polygon’s vertices are shaded and the polygon is clipped and possibly culled before these modes are applied.

The point size of the final rasterization of polygons when fill mode is POINT is implementation-dependent, and the point size may either be PointSize or 1.0.

## Depth Bias

The depth values of all fragments generated by the rasterization of a polygon can be biased (offset) by a single depth bias value that is computed for that polygon.

### Depth Bias Enable

The depth bias computation is enabled by the depthBiasEnable set with AfxCmdEnableDepthBias or the corresponding depthBiasEnabled value used to create the currently active pipeline. If the depth bias enable is FALSE, no bias is applied and the fragment’s depth values are unchanged.

To dynamically enable whether to bias fragment depth values, call:

```
void AfxCmdEnableDepthBias
(
afxDrawScript dscr, /// is the command buffer into which the command will be recorded.
afxBool enabled /// controls whether to bias fragment depth values.
);
```

This command sets the depth bias enable for subsequent drawing commands when the graphics pipeline is created with VK_DYNAMIC_STATE_DEPTH_BIAS_ENABLE set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the depthBiasEnable value used to create the currently active pipeline.

### Depth Bias Computation

The depth bias depends on three parameters:

- depthBiasSlopeFactor scales the maximum depth slope m of the polygon
- depthBiasConstantFactor scales the parameter r of the depth attachment
- the scaled terms are summed to produce a value which is then clamped to a minimum or

maximum value specified by depthBiasClamp

depthBiasSlopeFactor, depthBiasConstantFactor, and depthBiasClamp can each be positive, negative, or zero. These parameters are set as described for vkCmdSetDepthBias below.

The maximum depth slope m of a triangle is

[formula]

where (xf, yf, zf) is a point on the triangle. m may be approximated as

[formula]

r is the minimum resolvable difference that depends on the depth attachment representation. It is the smallest difference in framebuffer coordinate z values that is guaranteed to remain distinct throughout polygon rasterization and in the depth attachment. All pairs of fragments generated by the rasterization of two polygons with otherwise identical vertices, but zf values that differ by r, will have distinct depth values.

For fixed-point depth attachment representations, r is constant throughout the range of the entire depth attachment.

Its value is implementation-dependent but must be at most

r = 2 × 2-n

where n is the number of bits used for the depth aspect.

For floating-point depth attachment, there is no single minimum resolvable difference. In this case, the minimum resolvable difference for a given polygon is dependent on the maximum exponent, e, in the range of z values spanned by the primitive. If n is the number of bits in the floating-point mantissa, the minimum resolvable difference, r, for the given primitive is defined as

r = 2e-n

If no depth attachment is present, r is undefined.

The bias value o for a polygon is

[formula]

m is computed as described above. If the depth attachment uses a fixed-point representation, m is a function of depth values in the range [0,1], and o is applied to depth values in the same range.

Depth bias is applied to triangle topology primitives received by the rasterizer regardless of polygon mode. Depth bias may also be applied to line and point topology primitives received by the rasterizer.

To dynamically set the depth bias parameters, call:

```
void AfxCmdSetDepthBias
(
afxDrawScript dscr, /// is the command buffer into which the command will be recorded.
afxReal constFactor, /// is a scalar factor controlling the constant depth value added to each
fragment.
afxReal clamp, /// is the maximum (or minimum) depth bias of a fragment.
afxReal slopeFactor /// is a scalar factor applied to a fragment’s slope in depth bias calculations.
);
```

This command sets the depth bias parameters for subsequent drawing commands when the graphics pipeline is created with VK_DYNAMIC_STATE_DEPTH_BIAS set in VkPipelineDynamicStateCreateInfo::pDynamicStates. Otherwise, this state is specified by the corresponding depthBiasConstantFactor, depthBiasClamp, and depthBiasSlopeFactor values used to create the currently active pipeline.

## Responses