The Framebuffer
Blending
Blending combines the incoming source fragment’s R, G, B, and A values with the destination R, G, B, and A values of each sample stored in the framebuffer at the fragment’s (xf,yf) location. If any components are missing in the framebuffer attachment, they are replaced as described in Component Substitution. Blending is performed for each color sample covered by the fragment, rather than just once for each fragment.
Source and destination values are combined according to the blend operation, quadruplets of source and destination weighting factors determined by the blend factors, and a blend constant, to obtain a new set of R, G, B, and A values, as described below.
Blending is computed and applied separately to each color attachment used by the subpass, with separate controls for each attachment.
Prior to performing the blend operation, signed and unsigned normalized fixed-point color components undergo an implied conversion to floating-point as specified by Conversion from Normalized Fixed-Point to Floating-Point. Blending computations are treated as if carried out in floating-point, and basic blend operations are performed with a precision and dynamic range no lower than that used to represent destination components. Advanced blending operations are performed with a precision and dynamic range no lower than the smaller of that used to represent destination components or that used to represent 16-bit floating-point values.
VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT.The pipeline blend state is included in the
VkPipelineColorBlendStateCreateInfo structure during graphics pipeline
creation:
Blend Factors
Dual-Source Blending
Blend factors that use the secondary color input
(Rs1,Gs1,Bs1,As1) (VK_BLEND_FACTOR_SRC1_COLOR,
VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR,
VK_BLEND_FACTOR_SRC1_ALPHA, and
VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA) may consume implementation
resources that could otherwise be used for rendering to multiple color
attachments.
Therefore, the number of color attachments that can be used in a
framebuffer may be lower when using dual-source blending.
Dual-source blending is only supported if the dualSrcBlend feature is enabled.
The maximum number of color attachments that can be used in a subpass when
using dual-source blending functions is implementation-dependent and is
reported as the maxFragmentDualSrcAttachments member of
VkPhysicalDeviceLimits.
Color outputs can be bound to the first and second inputs of the blender
using the Index decoration, as described in
Fragment Output Interface.
If the second color input to the blender is not written in the shader, or if
no output is bound to the second input of a blender, the value of the second
input is undefined.
Blend Operations
If the numeric format of a framebuffer attachment
uses sRGB encoding, the R, G, and B destination color values (after
conversion from fixed-point to floating-point) are considered to be encoded
for the sRGB color space and hence are linearized prior to their use in
blending.
Each R, G, and B component is converted from nonlinear to linear as
described in the sRGB EOTF section of the Khronos Data
Format Specification.
If the format is not sRGB, no linearization is performed.
If the numeric format of a framebuffer attachment uses sRGB encoding, then the final R, G, and B values are converted into the nonlinear sRGB representation before being written to the framebuffer attachment as described in the sRGB EOTF -1 section of the Khronos Data Format Specification.
If the numeric format of a framebuffer color attachment is not sRGB encoded, then the resulting cs values for R, G, and B are unmodified.
The value of A is never sRGB encoded. That is, the alpha component is always stored in memory as linear.
If the framebuffer color attachment is VK_ATTACHMENT_UNUSED, no writes
are performed through that attachment.
Writes are not performed to framebuffer color attachments greater than or
equal to the VkSubpassDescription::colorAttachmentCount
or VkSubpassDescription2::colorAttachmentCount
value.
Advanced Blend Operations
The advanced blend operations are those listed in tables f/X/Y/Z Advanced Blend Operations, Hue-Saturation-Luminosity Advanced Blend Operations, and Additional RGB Blend Operations.
When using one of the operations in table f/X/Y/Z Advanced Blend Operations or Hue-Saturation-Luminosity Advanced Blend Operations, blending is performed according to the following equations:
where the function f and terms X, Y, and Z are specified in the table.
The R, G, and B components of the source color used for blending are derived
according to srcPremultiplied.
If srcPremultiplied is VK_TRUE, the fragment color components
are considered to have been premultiplied by the A component prior to
blending.
The base source color (Rs',Gs',Bs') is obtained by dividing
through by the A component:
If srcPremultiplied is VK_FALSE, the fragment color components
are used as the base color:
The R, G, and B components of the destination color used for blending are
derived according to dstPremultiplied.
If dstPremultiplied is VK_TRUE, the destination components are
considered to have been premultiplied by the A component prior to blending.
The base destination color (Rd',Gd',Bd') is obtained by dividing
through by the A component:
If dstPremultiplied is VK_FALSE, the destination color
components are used as the base color:
When blending using advanced blend operations, we expect that the R, G, and B components of premultiplied source and destination color inputs be stored as the product of non-premultiplied R, G, and B component values and the A component of the color. If any R, G, or B component of a premultiplied input color is non-zero and the A component is zero, the color is considered ill-formed, and the corresponding component of the blend result is undefined.
All of the advanced blend operation formulas in this chapter compute the
result as a premultiplied color.
If dstPremultiplied is VK_FALSE, that result color’s R, G, and B
components are divided by the A component before being written to the
framebuffer.
If any R, G, or B component of the color is non-zero and the A component is
zero, the result is considered ill-formed, and the corresponding component
of the blend result is undefined.
If all components are zero, that value is unchanged.
If the A component of any input or result color is less than zero, the color is considered ill-formed, and all components of the blend result are undefined.
| Mode | Blend Coefficients |
|---|---|
VK_BLEND_OP_ZERO_EXT | $$ |
\begin{aligned}
(X,Y,Z) & = (0,0,0) \\
f(C_s,C_d) & = 0
\end{aligned}
\begin{aligned} (R_s', G_s', B_s') & = \begin{cases} (R_s, G_s, B_s) & \text{if srcPremultiplied is VK_TRUE} \ (R_sA_s, G_sA_s, B_sA_s) & \text{if srcPremultiplied is VK_FALSE} \end{cases} \ (R_d', G_d', B_d') & = \begin{cases} (R_d, G_d, B_d) & \text{if dstPremultiplied is VK_TRUE} \ (R_dA_d, G_dA_d, B_dA_d) & \text{if dstPremultiplied is VK_FALSE} \end{cases} \end{aligned}
| Mode | Result | | ---------------------- | ------ | | `VK_BLEND_OP_PLUS_EXT` | $$ | ``` \begin{aligned} (R,G,B,A) = ( & R_s'+R_d', \\ & G_s'+G_d', \\ & B_s'+B_d', \\ & A_s+A_d) \end{aligned} ``` $$ | \| `VK_BLEND_OP_PLUS_CLAMPED_EXT` | $$ \begin{aligned} (R,G,B,A) = ( & min(1,R\_s'+R\_d'), \\ & min(1,G\_s'+G\_d'), \\ & min(1,B\_s'+B\_d'), \\ & min(1,A\_s+A\_d)) \end{aligned} $$ | \| `VK_BLEND_OP_PLUS_CLAMPED_ALPHA_EXT` | $$ \begin{aligned} (R,G,B,A) = ( & min(min(1,A\_s+A\_d),R\_s'+R\_d'), \\ & min(min(1,A\_s+A\_d),G\_s'+G\_d'), \\ & min(min(1,A\_s+A\_d),B\_s'+B\_d'), \\ & min(1,A\_s+A\_d)) \end{aligned} $$ | \| `VK_BLEND_OP_PLUS_DARKER_EXT` | $$ \begin{aligned} (R,G,B,A) = ( & max(0,min(1,A\_s+A\_d)-((A\_s-R\_s')+(A\_d-R\_d'))), \\ & max(0,min(1,A\_s+A\_d)-((A\_s-G\_s')+(A\_d-G\_d'))), \\ & max(0,min(1,A\_s+A\_d)-((A\_s-B\_s')+(A\_d-B\_d'))), \\ & min(1,A\_s+A\_d)) \end{aligned} $$ | \| `VK_BLEND_OP_MINUS_EXT` | $$ \begin{aligned} (R,G,B,A) = ( & R\_d'-R\_s', \\ & G\_d'-G\_s', \\ & B\_d'-B\_s', \\ & A\_d-A\_s) \end{aligned} $$ | \| `VK_BLEND_OP_MINUS_CLAMPED_EXT` | $$ \begin{aligned} (R,G,B,A) = ( & max(0,R\_d'-R\_s'), \\ & max(0,G\_d'-G\_s'), \\ & max(0,B\_d'-B\_s'), \\ & max(0,A\_d-A\_s)) \end{aligned} $$ | \| `VK_BLEND_OP_CONTRAST_EXT` | $$ \begin{aligned} (R,G,B,A) = ( & \frac{A\_d}{2} + 2(R\_d'-\frac{A\_d}{2})(R\_s'-\frac{A\_s}{2}), \\ & \frac{A\_d}{2} + 2(G\_d'-\frac{A\_d}{2})(G\_s'-\frac{A\_s}{2}), \\ & \frac{A\_d}{2} + 2(B\_d'-\frac{A\_d}{2})(B\_s'-\frac{A\_s}{2}), \\ & A\_d) \end{aligned} $$ | \| `VK_BLEND_OP_INVERT_OVG_EXT` | $$ \begin{aligned} (R,G,B,A) = ( & A\_s(1-R\_d') + (1-A\_s)R\_d', \\ & A\_s(1-G\_d') + (1-A\_s)G\_d', \\ & A\_s(1-B\_d') + (1-A\_s)B\_d', \\ & A\_s+A\_d-A\_sA\_d) \end{aligned} $$ | \| `VK_BLEND_OP_RED_EXT` | $$ \begin{aligned} (R,G,B,A) & = (R\_s', G\_d', B\_d', A\_d) \end{aligned} $$ | \| `VK_BLEND_OP_GREEN_EXT` | $$ \begin{aligned} (R,G,B,A) & = (R\_d', G\_s', B\_d', A\_d) \end{aligned} $$ | \| `VK_BLEND_OP_BLUE_EXT` | $$ \begin{aligned} (R,G,B,A) & = (R\_d', G\_d', B\_s', A\_d) \end{aligned} $$ | ## #framebuffer-logicop Logical Operations The application :normative{type="can"} enable a *logical operation* between the fragment’s color values and the existing value in the framebuffer attachment. This logical operation is applied prior to updating the framebuffer attachment. Logical operations are applied only for signed and unsigned integer and normalized integer framebuffers. Logical operations are not applied to floating-point or sRGB format color attachments. ::refpage{name="VkLogicOp" type="enums"} Framebuffer logical operations :: ::refpage{name="vkCmdSetLogicOpEnableEXT" type="protos"} Specify dynamically whether logical operations are enabled for a command buffer :: ::refpage{name="vkCmdSetLogicOpEXT" type="protos"} Select which logical operation to apply for blend state dynamically for a command buffer :: ## #framebuffer-color-write-mask Color Write Mask ::refpage{name="VkColorComponentFlagBits" type="enums"} Bitmask controlling which components are written to the framebuffer :: ::refpage{name="VkColorComponentFlags" type="flags"} Bitmask of VkColorComponentFlagBits :: ## #framebuffer-color-write-enable Color Write Enable ::refpage{name="VkPipelineColorWriteCreateInfoEXT" type="structs"} Structure specifying color write state of a newly created pipeline :: ::refpage{name="vkCmdSetColorWriteEnableEXT" type="protos"} Enable or disable writes to a color attachment dynamically for a command buffer :: ## #framebuffer-queries Framebuffer Query Instructions ::refpage{name="vkGetFramebufferTilePropertiesQCOM" type="protos"} Get tile properties from the attachments in framebuffer ::