赞
踩
颜色混合
在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;
你可以在规范文档中的VkBlendFactor和VkBlendOp枚举中找到所有可能的操作。
第二个结构体是对所有的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中。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。