OpenGL混合函数和图片混合模式

一、OpenGL函数提供两个:

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)
查看每个通道的颜色信息,并将混合色的互补色与基色进行正片叠底。结果色总是较亮的颜色。用黑色过滤时颜色保持不变。用白色过滤将产生白色。此效果类似于多个摄影幻灯片在彼此之上投影。

三、shader实现

参考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。

你可能感兴趣的:(计算机图形学)