当前位置:   article > 正文

Vulkan - Color Blending_vkpipelinecolorblendattachmentstate开启颜色混合

vkpipelinecolorblendattachmentstate开启颜色混合

原文:Vulkan Color Blending

Color Blending

颜色混合

在fragment shader返回颜色后,需要将它与存储在framebuffer的颜色组合。这就是周所周知的颜色混合color blending,有两种方式可以做到:

  • 混合旧的、新的颜色来生成一个最终颜色
  • 使用位运算方式来组合旧的、新的颜色

有两种结构体类型来配置颜色混合。第一个结构体是: VKPipelineColorBlendAttachmentState 包含了每个附件到framebuffer的配置,而第二个结构体是: VkPipelineColorBlendStateCreateInfo 包含全局的颜色混合设置。在我们这个例子仅有一个framebuffer。

VkPipelineColorBlendAttachmentState colorBlendAttachment = {};
colorBlendAttachment.colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
colorBlendAttachment.blendEnable = VK_FALSE;
colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_ONE; // 可选
colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; // 可选
colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD; // 可选
colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; // 可选
colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; // Optional
colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD; // Optional
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

这个对每个framebuffer生效的结构体允许你配置第一种方式的颜色混合。它将用于类似下面的伪代码中应用:

if (blendEnable) {
    finalColor.rgb = (srcColorBlendFactor * newColor.rgb) <colorBlendOp> (dstColorBlendFactor * oldColor.rgb);
    finalColor.a = (srcAlphaBlendFactor * newColor.a) <alphaBlendOp> (dstAlphaBlendFactor * oldColor.a);
} else {
    finalColor = newColor;
}

finalColor = finalColor & colorWriteMask;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

如果blendEnable 设置为 VK_FALSE,那么从fragment shader结构得出的新颜色将不做修改就传给到新的颜色。否则,处理两个混合操作(color blend和alpha blend)来算出新的颜色。然后新的颜色再与 colorWriteMask 位的与运算来决定哪个通道才能通过。

多数使用颜色混合的方式是使用alpha混合,我们想要将新的颜色与旧的颜色及与他们的透明度来混合。最终的颜色 finalColor 将被算出来,如下伪代码:

finalColor.rgb = newAlpha * newColor + (1 - newAlpha) * oldColor;
finalColor.a = newAlpha.a;
  • 1
  • 2

可以用下面的参数配置方式来实现:

colorBlendAttachment.blendEnable = VK_TRUE;
colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA;
colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

你可以在规范文档中的VkBlendFactorVkBlendOp枚举中找到所有可能的操作。

第二个结构体是对所有的framebuffers生效,并允许设置混合常量,来给上面提到的伪代码计算中,提供混合因子的计算。

VkPipelineColorBlendStateCreateInfo colorBlending = {};
colorBlending.sType = VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO;
colorBlending.logicOpEnable = VK_FALSE;
colorBlending.logicOp = VK_LOGIC_OP_COPY; // 可选
colorBlending.attachmentCount = 1;
colorBlending.pAttachments = &colorBlendAttachment;
colorBlending.blendConstants[0] = 0.0f; // 可选
colorBlending.blendConstants[1] = 0.0f; // 可选
colorBlending.blendConstants[2] = 0.0f; // 可选
colorBlending.blendConstants[3] = 0.0f; // 可选
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

如果你想使用第二种混合方式(位操作组合方式),那么你应用将 logicOpEnable 设置为 VK_TRUE。位操作可以通过设置 logicOp 字段控制。注意这将会自动禁用掉第一种方式,就如将对每个附加到framebuffer的混合配置的 blendEnable 设置为 VK_FALSE 一样。 colorWriteMask 将会在这种方式中继续使用,来决定哪个通道可以作用到framebuffer中。当然也可能是将这两种方式都禁用了,就像我们上面的代码设置一样,fragment输出的颜色将会不做修改的写入到framebuffer中。

References

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/96792
推荐阅读
相关标签
  

闽ICP备14008679号