openGL中的混合
目标色:Dc 源色:Sc
目标色系数:Ds 原色系数:Ss
关于目标色和原色系数的计算方法,一共有如下的选项:
GL_ZERO (0,0,0)
GL_ONE (1,1,1)
GL_SRC_COLOR (Rs,Gs,Bs)
GL_ONE_MINUS_SRC_COLOR (1 - Rs,1 - Gs,1 - Bs)
GL_DST_COLOR (Rd,Gd,Bd)
GL_ONE_MINUS_DST_COLOR (1 - Rd,1 - Gd,1 - Bd)
GL_SRC_ALPHA (As,As,As)
GL_ONE_MINUS_SRC_ALPHA (1 - As,1 - As,1 - As)
GL_DST_ALPHA (Ad,Ad,Ad)
GL_ONE_MINUS_DST_ALPHA (1 - Ad,1 - Ad,1 - Ad)
GL_SRC_ALPHA_SATURATE (f,f,f) f=min(As,1 - Ad)
目标色和原色分别乘以系数计算后,将得到的两个值按照一定方法计算,就可以得到最后混合的颜色,计算方式包括:
GL_FUNC_ADD ScSs + DcDs
GL_FUNC_SUBTRACT ScSs - DcDs
GL_FUNC_REVERSE_SUBTRACT DcDs - ScSs
GL_MIN min(ScSs,DcDs)
GL_MAX max(ScSs,DcDs)
需要说明的是,默认情况下,目标色和原色的结合采用的是 GL_FUNC_ADD的方式。
另外需要说明的是,有另外两个函数 glBlendFuncSeparate和glBlendEquationSeparate分别设置rgb色和alpha的混合方式(第一个函数设置混合参数,第二个参数设置目标色和原色的混合计算方式)
一个完整的混合流程应该包括如下的三个步骤:
//开启混合
glEnable(GL_BLEND);
//设置混合方式
glBlendEquation(GL_FUNC_ADD);
//设置混合参数生成方式
glBlendFunc(sfactor, dfactor);
首先使用glEnable设置开启混合,然后通过调用glBlendEquation设置目标色和原色的结合方式,最后调用glBlendFunc设置原色和目标色系数的生成方式。
通过下面一个例子会更加深入的理解混合,在adobe的软件中有一个效果叫滤色,滤色是混合模式,存在于颜色混合模式、通道混合模式、图层混合模式的变亮模式组中。混合后的效果类似于多个摄影幻灯片在彼此之上投影。
使用滤色和不使用滤色的效果对比:
左边是使用滤色后的混合效果。
滤色的公式是:
结果色 = 1 - (1 - 原色)* (1 - 目标色)
= 1 - (1 + 原色 * 目标色 - 原色 - 目标色)
= 原色 + 目标色 - 原色 * 目标色
= 1 * 原色 + (1 - 原色)* 目标色
原色的系数是1,目标色的系数是(1 - 原色)
得出的结论是目标色和原色的系数分别是:
blendFunc.src = GL_ONE
blendFunc.dst = GL_ONE_MINUS_SRC_COLOR
这里再分享一个使用滤色的小技巧,在lua中尤其实用,不需要直接创建一个BlendFunc,可以先从精灵中获得这个对象,然后进行修改
local blendFunc = sp:getBlendFunc()
blendFunc.src = GL_ONE
blendFunc.dst = GL_ONE_MINUS_SRC_COLOR
sp:setBlendFunc(blendFunc)
能力不足,水平有限,如有错误,欢迎指出。