您当前的位置: 首页 > 

Jave.Lin

暂无认证

  • 1浏览

    0关注

    704博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Vulkan - Color Blending

Jave.Lin 发布时间:2019-07-05 14:05:32 ,浏览量:1

原文: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)  (dstColorBlendFactor * oldColor.rgb);
    finalColor.a = (srcAlphaBlendFactor * newColor.a)  (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中。

References
  • Vulkan - Color Blending
  • Vulkan - Blending Factor Enum
  • Vulkan - Blending Op Enum
关注
打赏
1664331872
查看更多评论
立即登录/注册

微信扫码登录

0.0409s