Vulkan - Color Blending

原文: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

这个对每个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;

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

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

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

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

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;

你可以在规范文档中的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; // 可选

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

References

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值