glBlendFunc (GLenum sfactor, GLenum dfactor)
和
glBlendFuncSeparate (GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
释义:
glBlendFunc
用来设置计算时两个颜色的混合因子;两个颜色分别是源图像(提供的素材图)和目标图像(buffer中已经画好的图)。(注意这里只是提供混合因子,颜色还是由源图和目标图提供);
glBlendFuncSeparate
用来设置颜色和透明度的混合因子。前两个参数是颜色混合因子,与glBlendFunc作用一样;后面两个参数是透明度混合因子,用于计算结果图的透明度。
参考Adobe Photoshop的简介https://helpx.adobe.com/cn/photoshop/using/blending-modes.html,挑选几种常用的罗列如下:
正常(Normal)
编辑或绘制每个像素,使其成为结果色。这是默认模式。(在处理位图图像或索引颜色图像时,“正常”模式也称为阈值。)
备注:如果带透明度,就是根据透明度混合。
正片叠底(Multiply)
查看每个通道中的颜色信息,并将基色与混合色进行正片叠底。结果色总是较暗的颜色。任何颜色与黑色正片叠底产生黑色。任何颜色与白色正片叠底保持不变。当您用黑色或白色以外的颜色绘画时,绘画工具绘制的连续描边产生逐渐变暗的颜色。这与使用多个标记笔在图像上绘图的效果相似。
滤色(Screen)
查看每个通道的颜色信息,并将混合色的互补色与基色进行正片叠底。结果色总是较亮的颜色。用黑色过滤时颜色保持不变。用白色过滤将产生白色。此效果类似于多个摄影幻灯片在彼此之上投影。
参考https://github.com/jamieowen/glsl-blend
举例:
Normal混合方式
vec3 blendNormal(vec3 base, vec3 blend) {
return blend;
}
vec3 blendNormal(vec3 base, vec3 blend, float opacity) {
return (blendNormal(base, blend) * opacity + base * (1.0 - opacity));
}
Multiply混合方式
vec3 blendMultiply(vec3 base, vec3 blend) {
return base*blend;
}
vec3 blendMultiply(vec3 base, vec3 blend, float opacity) {
return (blendMultiply(base, blend) * opacity + base * (1.0 - opacity));
}
Screen混合方式
float blendScreen(float base, float blend) {
return 1.0-((1.0-base)*(1.0-blend));
}
vec3 blendScreen(vec3 base, vec3 blend) {
return vec3(blendScreen(base.r,blend.r),blendScreen(base.g,blend.g),blendScreen(base.b,blend.b));
}
vec3 blendScreen(vec3 base, vec3 blend, float opacity) {
return (blendScreen(base, blend) * opacity + base * (1.0 - opacity));
}
参考:https://cloud.tencent.com/developer/article/1121722
前置说明:T是混合后的像素颜色,S表示用于混合的素材像素颜色,D表示底图的像素颜色(S,D,T的取值范围都是0~1)。
混合模式 | 公式 | 条件 |
---|---|---|
Normal | T=S | |
multiply | T=S*D | |
screen | T=1-(1-S)*(1-D) | |
overlay | T=2SD | D<0.5 |
T=1-2*(1-S)*(1-D) | D>=0.5 | |
hardlight | T= 2*S*D | S<0.5 |
T=1-2*(1-S)*(1-D) | S>=0.5 | |
softlight | T=2*S*D+D*D*(1-2*S) | S<0.5 |
T=2*D*(1-S)+sqrt(D)(2S-1) | S>=0.5 | |
divide | T=D/S | D/S取0~1之间 |
add | T=D+S | D+S取0~1之间 |
subtract | T=D-S | D-S取0~1之间 |
diff | T=|D-S| | |
darken | T=MIN(D,S) | |
lighten | T=MAX(D,S) |
后置说明:当融合图片是半透明的时候(α值不是1),融合后的像素值*T’=T*α+(1-α)D。从中可以看出,当α为0时(全透明),T’=D,即融合图片不影响结果;当α为1时(不透明),T’=T。