A point is drawn by generating a set of fragments in the shape of a square centered around the vertex of the point. Each vertex has an associated point size controlling the width/height of that square. The point size is taken from the (potentially clipped) shader built-in PointSize written by:
- the geometry shader, if active;
- the tessellation evaluation shader, if active and no geometry shader is active;
- the vertex shader, otherwise
and clamped to the implementation-dependent point size range [pointSizeRange, pointSizeRange]. The value written to PointSize must be greater than zero.
Not all point sizes need be supported, but the size 1.0 must be supported. The range of supported sizes and the size of evenly-spaced gradations within that range are implementation-dependent. The range and gradations are obtained from the pointSizeRange and pointSizeGranularity 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 sizes 0.1, 0.2, …, 1.9, 2.0 are supported. Additional point sizes may also be supported.
There is no requirement that these sizes be equally spaced. If an unsupported size is requested, the nearest supported size is used instead.
Basic Point Rasterization
Point rasterization produces a fragment for each fragment area group of framebuffer pixels with one or more sample points that intersect a region centered at the point’s (xf, yf). This region is a square with side equal to the current point size. Coverage bits that correspond to sample points that intersect the region are 1, other coverage bits are 0. All fragments produced in rasterizing a point are assigned the same associated data, which are those of the vertex corresponding to the point.
However, the fragment shader built-in PointCoord contains point sprite texture coordinates. The s and t point sprite texture coordinates vary from zero to one across the point horizontally left-toright and vertically top-to-bottom, respectively. The following formulas are used to evaluate s and t:
s = (1 / 2) + ((Xp – Xf) / size)
t = (1 / 2) + ((Yp – Yf) / size)
where size is the point’s size; (xp,yp) is the location at which the point sprite coordinates are evaluated – this may be the framebuffer coordinates of the fragment center, or the location of a sample; and (xf, yf) is the exact, unrounded framebuffer coordinate of the vertex for the point.