Link

当我们创建管线构建器时,我们完全跳过了混合逻辑,将其设置为不混合。混合用于透明对象和一些图形效果,因此拥有它很重要。因此,我们将使我们在上一篇文章中渲染的矩形透明。

管线中的混合

我们无法真正从着色器控制混合,那是管线的属性。GPU 硬件本身为我们进行混合数学运算,并有许多选项。我们将在管线构建器中添加 2 种新的混合模式,一种是加法混合,它只是添加颜色,另一种是 alpha 混合,它将混合颜色。

让我们将这两个函数添加到管线构建器中

void PipelineBuilder::enable_blending_additive()
{
    _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_TRUE;
    _colorBlendAttachment.srcColorBlendFactor = VK_BLEND_FACTOR_SRC_ALPHA;
    _colorBlendAttachment.dstColorBlendFactor = VK_BLEND_FACTOR_ONE;
    _colorBlendAttachment.colorBlendOp = VK_BLEND_OP_ADD;
    _colorBlendAttachment.srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE;
    _colorBlendAttachment.dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO;
    _colorBlendAttachment.alphaBlendOp = VK_BLEND_OP_ADD;
}

void PipelineBuilder::enable_blending_alphablend()
{
    _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_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;
}

在 Vulkan 中设置混合选项时,我们需要填充颜色和 alpha 的公式。参数在颜色和 alpha 上工作方式相同。公式如下

outColor = srcColor * srcColorBlendFactor <op> dstColor * dstColorBlendFactor;

有一些可能的运算符,但在大多数情况下,我们将使用 VK_BLEND_OP_ADD,因为它是最基本且保证可以工作的。还有许多其他更高级的运算符,但这些运算符带有扩展,我们不会使用它们。源(来自 srcColor 和混合因子)指的是我们在管线上处理的颜色,目标(dstColor 和混合因子)是我们正在渲染到的图像的当前值。

有了上面的公式,让我们解释一下加法混合的作用。

VK_BLEND_FACTOR_ONE 将混合因子设置为 1.0,因此不进行乘法运算。另一方面,VK_BLEND_FACTOR_SRC_ALPHA 将其乘以源的 alpha 值。我们的混合最终变成这个公式

outColor = srcColor.rgb * srcColor.a + dstColor.rgb * 1.0

alpha 混合的公式将如下所示。

outColor = srcColor.rgb * srcColor.a + dstColor.rgb * (1.0 - srcColor.a)

本质上使其成为由 srcColor alpha 控制的 lerp,这将来自我们的着色器。

让我们尝试使用它来看看它的作用。我们的着色器中没有设置 alpha,所以让我们尝试加法混合。更改 init_mesh_pipeline() 函数上的混合。

//pipelineBuilder.disable_blending();
pipelineBuilder.enable_blending_additive();

现在您应该看到猴子网格是半透明的,让下面的颜色显示出来。尝试使用不同的混合模式,看看它们会产生什么效果。

在我们进入第 4 章之前,让我们实现窗口调整大小。

下一步: 窗口调整大小