Blending Stageの指定
Blending Stage
Blending Stageではcolor blendの指定を行う。
aqoole-hateena.hatenablog.com
color blendとは
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. Blending is performed for each color sample covered by the fragment, rather than just once for each fragment.
Vulkan® 1.2.203 - A Specification (with all registered Vulkan extensions)
color blendとは、source colorとdst colorのfragments(RGBA)を混ぜ合わせて、対応するframe bufferの位置(, )に格納することである。
つまりsource color, dst colorの選び方と、色の混ぜ方を決めることが重要となる。
VkPipelineColorBlendStateCreateInfo
VkPipelineColorBlendStateCreateInfo - Structure specifying parameters of a newly created pipeline color blend state
// Provided by VK_VERSION_1_0 typedef struct VkPipelineColorBlendStateCreateInfo { VkStructureType sType; const void* pNext; VkPipelineColorBlendStateCreateFlags flags; VkBool32 logicOpEnable; VkLogicOp logicOp; uint32_t attachmentCount; const VkPipelineColorBlendAttachmentState* pAttachments; float blendConstants[4]; } VkPipelineColorBlendStateCreateInfo;
- flags is a bitmask of VkPipelineColorBlendStateCreateFlagBits specifying additional color blending information.
- logicOpEnable controls whether to apply Logical Operations.
- logicOp selects which logical operation to apply.
- attachmentCount is the number of VkPipelineColorBlendAttachmentState elements in pAttachments.
- pAttachments is a pointer to an array of VkPipelineColorBlendAttachmentState structures defining blend state for each color attachment.
- blendConstants is a pointer to an array of four values used as the R, G, B, and A components of the blend constant that are used in blending, depending on the blend factor.
flags
現状、設定できるパラメータは1種類だけのよう。
// Provided by VK_ARM_rasterization_order_attachment_access typedef enum VkPipelineColorBlendStateCreateFlagBits { // Provided by VK_ARM_rasterization_order_attachment_access VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_ARM = 0x00000001, } VkPipelineColorBlendStateCreateFlagBits;
VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_ARM indicates that access to color and input attachments will have implicit framebuffer-local memory dependencies, allowing applications to express custom blending operations in a fragment shader. See renderpass feedback loops for more information.
VkPipelineColorBlendStateCreateFlagBits(3)
内容が理解できないので、仕様書の拡張機能について書かれてある部分を見てみる。
VK_ARM_rasterization_order_attachment_access
Renderpasses, and specifically subpass self-dependencies enable much of the same functionality as the framebuffer fetch and pixel local storage extensions did for OpenGL ES. But certain techniques such as programmable blending are awkward or impractical to implement with these alone, in part because a self-dependency is required every time a fragment will read a value at a given sample coordinate.
This extension extends the mechanism of input attachments to allow access to framebuffer attachments when used as both input and color, or depth/stencil, attachments from one fragment to the next, in rasterization order, without explicit synchronization.
Vulkan® 1.2.203 - A Specification (with all registered Vulkan extensions)
「fragmentがsample coordinateを読み込む場合に、常に自己依存が要求されることもあり、programmable blendingのような技術をRenderpassesとspecifically subpass self-dependenciesだけで実装するのは、あまりよくない」とある。color blendingをprogrammableにするには、通常のrenderpassとsubpassだけでは足りないようだ。
そこでこの拡張機能では、input attachmentsとcolor or depth/stencial attachments)の両方が使用されている場合に、明示的なsynchroなしでinput attachmentがframebuffer attachmentにアクセスすることを可能にする、とある。
Feedback loops
If a subpass uses the same attachment as both an input attachment and either a color attachment or a depth/stencil attachment, writes via the color or depth/stencil attachment are not automatically made visible to reads via the input attachment, causing a feedback loop, except in any of the following conditions:
Vulkan® 1.2.203 - A Specification (with all registered Vulkan extensions)
subpassがinput attachmentとcolor or depth/stencial attachmentの両方を持つとき、color or depth/stencial attachmentからの書き込みは、input attachmentから自動的に読み込めるようにvisibleの状態にはならない、とある。そしてこれがfeedback loopを生み出すとある。
Rendering within a subpass containing a feedback loop creates a data race, except in the following cases:
- If the attachment is used as color and input attachment, and the pipeline performing the read was created with VK_PIPELINE_COLOR_BLEND_STATE_CREATE_RASTERIZATION_ORDER_ATTACHMENT_ACCESS_BIT_ARM included in the flags member of the pColorBlendState member of its VkGraphicsPipelineCreateInfo. This creates a framebuffer-local memory dependency for each fragment generated by draw commands using this pipeline with the following properties:
- The first synchronization scope includes the VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT pipeline stage executed by all previous fragments (as defined by primitive order) in the corresponding framebuffer regions including those generated by the same draw command.
- The second synchronization scope includes the VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT pipeline stage executed by the generated fragment.
- The first access scope includes all writes to color attachments.
- The second access scope includes all reads from input attachments.
feedback loopsをもつsubpassでのrenderingではdata race(データ競合)が発生してしまうが、拡張機能を設定しておけば回避できる。拡張を設定することにより、各fragmentについてlocal memory依存のframebufferを作成できる。sync scopeとaccess scopeは書かれてある通りである。
logicOpEnable
The application 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.
Vulkan® 1.2.203 - A Specification (with all registered Vulkan extensions)
logical operationsとは、fragmentの色とframe bufferに保存されている色の論理演算のことである。この演算はframe buffer attachmentが更新されるよりも前に行われる。logical operationsは整数型(signed, unsigned)のframe bufferにのみ適用される。
logicOpEnableはこの論理演算を行うかどうかを設定する。
logicOp
// Provided by VK_VERSION_1_0 typedef enum VkLogicOp { VK_LOGIC_OP_CLEAR = 0, VK_LOGIC_OP_AND = 1, VK_LOGIC_OP_AND_REVERSE = 2, VK_LOGIC_OP_COPY = 3, VK_LOGIC_OP_AND_INVERTED = 4, VK_LOGIC_OP_NO_OP = 5, VK_LOGIC_OP_XOR = 6, VK_LOGIC_OP_OR = 7, VK_LOGIC_OP_NOR = 8, VK_LOGIC_OP_EQUIVALENT = 9, VK_LOGIC_OP_INVERT = 10, VK_LOGIC_OP_OR_REVERSE = 11, VK_LOGIC_OP_COPY_INVERTED = 12, VK_LOGIC_OP_OR_INVERTED = 13, VK_LOGIC_OP_NAND = 14, VK_LOGIC_OP_SET = 15, } VkLogicOp;
Mode | Operation |
---|---|
VK_LOGIC_OP_CLEAR | 0 |
VK_LOGIC_OP_AND | s ∧ d |
VK_LOGIC_OP_AND_REVERSE | s ∧ ¬ d |
VK_LOGIC_OP_COPY | s |
VK_LOGIC_OP_AND_INVERTED | ¬ s ∧ d |
VK_LOGIC_OP_NO_OP | d |
VK_LOGIC_OP_XOR | s ⊕ d |
VK_LOGIC_OP_OR | s ∨ d |
VK_LOGIC_OP_NOR | ¬ (s ∨ d) |
VK_LOGIC_OP_EQUIVALENT | ¬ (s ⊕ d) |
VK_LOGIC_OP_INVERT | ¬ d |
VK_LOGIC_OP_OR_REVERSE | s ∨ ¬ d |
VK_LOGIC_OP_COPY_INVERTED | ¬ s |
VK_LOGIC_OP_OR_INVERTED | ¬ s ∨ d |
VK_LOGIC_OP_NAND | ¬ (s ∧ d) |
VK_LOGIC_OP_SET | all 1s |
- s is the fragment’s , , or component value for the fragment output corresponding to the color attachment being updated, and
- d is the color attachment’s R, G, B or A component value
Vulkan® 1.2.203 - A Specification (with all registered Vulkan extensions)
pAttachments
VkPipelineColorBlendAttachmentState - Structure specifying a pipeline color blend attachment state
// Provided by VK_VERSION_1_0 typedef struct VkPipelineColorBlendAttachmentState { VkBool32 blendEnable; VkBlendFactor srcColorBlendFactor; VkBlendFactor dstColorBlendFactor; VkBlendOp colorBlendOp; VkBlendFactor srcAlphaBlendFactor; VkBlendFactor dstAlphaBlendFactor; VkBlendOp alphaBlendOp; VkColorComponentFlags colorWriteMask; } VkPipelineColorBlendAttachmentState;
- blendEnable controls whether blending is enabled for the corresponding color attachment. If blending is not enabled, the source fragment’s color for that attachment is passed through unmodified.
- srcColorBlendFactor selects which blend factor is used to determine the source factors (Sr,Sg,Sb).
- dstColorBlendFactor selects which blend factor is used to determine the destination factors (Dr,Dg,Db).
- colorBlendOp selects which blend operation is used to calculate the RGB values to write to the color attachment.
- srcAlphaBlendFactor selects which blend factor is used to determine the source factor Sa.
- dstAlphaBlendFactor selects which blend factor is used to determine the destination factor Da.
- alphaBlendOp selects which blend operation is use to calculate the alpha values to write to the color attachment.
- colorWriteMask is a bitmask of VkColorComponentFlagBits specifying which of the R, G, B, and/or A components are enabled for writing, as described for the Color Write Mask.
blendEnable
color blendingを実行するかどうかを決める。
srcColorBlendFactor
VkBlendFactor - Framebuffer blending factors
// Provided by VK_VERSION_1_0 typedef enum VkBlendFactor { VK_BLEND_FACTOR_ZERO = 0, VK_BLEND_FACTOR_ONE = 1, VK_BLEND_FACTOR_SRC_COLOR = 2, VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR = 3, VK_BLEND_FACTOR_DST_COLOR = 4, VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR = 5, VK_BLEND_FACTOR_SRC_ALPHA = 6, VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA = 7, VK_BLEND_FACTOR_DST_ALPHA = 8, VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA = 9, VK_BLEND_FACTOR_CONSTANT_COLOR = 10, VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR = 11, VK_BLEND_FACTOR_CONSTANT_ALPHA = 12, VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA = 13, VK_BLEND_FACTOR_SRC_ALPHA_SATURATE = 14, VK_BLEND_FACTOR_SRC1_COLOR = 15, VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR = 16, VK_BLEND_FACTOR_SRC1_ALPHA = 17, VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA = 18, } VkBlendFactor;
VkBlendFactor | RGB Blend Factors (Sr,Sg,Sb) or (Dr,Dg,Db) | Alpha Blend Factor (Sa or Da) |
---|---|---|
VK_BLEND_FACTOR_ZERO | (0,0,0) | 0 |
VK_BLEND_FACTOR_ONE | (1,1,1) | 1 |
VK_BLEND_FACTOR_SRC_COLOR | (Rs0,Gs0,Bs0) | As0 |
VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR | (1-Rs0,1-Gs0,1-Bs0) | 1-As0 |
VK_BLEND_FACTOR_DST_COLOR | (Rd,Gd,Bd) | Ad |
VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR | (1-Rd,1-Gd,1-Bd) | 1-Ad |
VK_BLEND_FACTOR_SRC_ALPHA | (As0,As0,As0) | As0 |
VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA | (1-As0,1-As0,1-As0) | 1-As0 |
VK_BLEND_FACTOR_DST_ALPHA | (Ad,Ad,Ad) | Ad |
VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA | (1-Ad,1-Ad,1-Ad) | 1-Ad |
VK_BLEND_FACTOR_CONSTANT_COLOR | (Rc,Gc,Bc) | Ac |
VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR | (1-Rc,1-Gc,1-Bc) | 1-Ac |
VK_BLEND_FACTOR_CONSTANT_ALPHA | (Ac,Ac,Ac) | Ac |
VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_ALPHA | (1-Ac,1-Ac,1-Ac) | 1-Ac |
VK_BLEND_FACTOR_SRC_ALPHA_SATURATE | (f,f,f); f = min(As0,1-Ad) | 1 |
VK_BLEND_FACTOR_SRC1_COLOR | (Rs1,Gs1,Bs1) | As1 |
VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR | (1-Rs1,1-Gs1,1-Bs1) | 1-As1 |
VK_BLEND_FACTOR_SRC1_ALPHA | (As1,As1,As1) | As1 |
VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA | (1-As1,1-As1,1-As1) | 1-As1 |
and represent the first source color R, G, B, and A components
and represent the second source color R, G, B, and A components, used in dual source blending modes
and represent the R, G, B, and A components of the destination color
and represent the blend constant R, G, B, and A components
VkBlendFactor(3)
source colorとして何を指定するのかを入力する。
colorBlendOp
// Provided by VK_VERSION_1_0 typedef enum VkBlendOp { VK_BLEND_OP_ADD = 0, VK_BLEND_OP_SUBTRACT = 1, VK_BLEND_OP_REVERSE_SUBTRACT = 2, VK_BLEND_OP_MIN = 3, VK_BLEND_OP_MAX = 4, } VkBlendOp;
VK_EXT_blend_operation_advancedの拡張機能を指定すれば、さらに多くのオプションを選べるようになる。
VkBlendOp(3)
それぞれのblendOpによる計算は以下の通り。
VkBlendOp | RGB Components | Alpha Component |
---|---|---|
VK_BLEND_OP_ADD | ||
VK_BLEND_OP_SUBTRACT | ||
VK_BLEND_OP_REVERSE_SUBTRACT | ||
VK_BLEND_OP_MIN | ||
VK_BLEND_OP_MAX |
出典 : Table 1. Basic Blend OperationsVkBlendOp(3)
: Source Blend Factor
: Destination Blend Facror
colorWriteMask
VkColorComponentFlagBits - Bitmask controlling which components are written to the framebuffer
Bits which can be set in VkPipelineColorBlendAttachmentState::colorWriteMask to determine whether the final color values R, G, B and A are written to the framebuffer attachment are:
// Provided by VK_VERSION_1_0 typedef enum VkColorComponentFlagBits { VK_COLOR_COMPONENT_R_BIT = 0x00000001, VK_COLOR_COMPONENT_G_BIT = 0x00000002, VK_COLOR_COMPONENT_B_BIT = 0x00000004, VK_COLOR_COMPONENT_A_BIT = 0x00000008, } VkColorComponentFlagBits;
The color write mask operation is applied regardless of whether blending is enabled.
VkColorComponentFlagBits(3)
color maskはどの色が最終的にframe bufferに格納されるかを決める。color maskはblendEnableの値に依らず参照される。もしmaskが指定されていなければ、frame bufferの値は更新されない。
blendConstants
srcColorBlendFactorの欄であるように、constant colorの値を指定する。