Cocos2d中使用颜色混合:加算,减算
在Cocos2d里,CCSprite 有一个 ccBlendFunc 类型的结构体成员 blendFunc_,它可用于设置绘制时的颜色混合方案。ccBlendFunc 包含 src 和 dst 两个成员,分别代表源和目标的运算因子。
若要对一个 Sprite 使用 setBlendFunc 方法,示例如下:
[Sprite setBlendFunc:(ccBlendFunc){GL_ONE, GL_ZERO}];
此操作会将该 Sprite 作为源,Sprite 所在位置的其他像素作为目标,进行混合运算。
设源的RGBA变量为:$R_s$、$G_s$、$B_s$、$A_s$;目标的RGBA为:$R_d$、$G_d$、$B_d$、$Ad$;源的各个运算因子为:$N{Rs}$、$N{Gs}$、$N{Bs}$、$N{As}$;目标的各个运算因子为:$N{Rd}$、$N{Gd}$、$N{Bd}$、$N{A_d}$。
那么混合后的RGBA值为:$(Rs \times N{R_s} + Rd \times N{R_d}, Gs \times N{G_s} + Gd \times N{G_d}, Bs \times N{B_s} + Bd \times N{B_d}, As \times N{A_s} + Ad \times N{A_d})$
常见的运算因子及其含义如下:
GL_ONE:表示因子值为 1.0GL_ZERO:表示因子值为 0.0GL_SRC_ALPHA:将源的Alpha值作为因子GL_DST_ALPHA:将目标的Alpha值作为因子GL_ONE_MINUS_SRC_ALPHA:以 1.0 减去源的Alpha值作为因子GL_ONE_MINUS_DST_ALPHA:以 1.0 减去目标的Alpha值作为因子
在 CCSprite 的 init 方法中,默认使用 GL_ONE 和 GL_ONE_MINUS_SRC_ALPHA 这两个参数。这就使得 Sprite 通常会覆盖下方的绘制内容,但如果 Sprite 存在透明区域,下方的颜色值会显示出来。
下面详细分析使用不同参数的效果:
- 不改变混合,使用默认情况:即使用
GL_ONE和GL_ONE_MINUS_SRC_ALPHA,Sprite会覆盖下方内容,透明区域显示下方颜色。 - 设置
glBlendFunc(GL_ONE, GL_ZERO):表面完全使用源颜色,效果等同于不进行混合。不过,若Sprite本身存在透明区域,这些区域会变成黑色,因为此时不显示目标颜色,即便透明度为 0 也无影响。 - 设置
glBlendFunc(GL_ZERO, GL_ONE):表示不使用源颜色,该Sprite不会被绘制出来。 - 使用与ALPHA相关的因子:会依据透明度进行计算,例如透明度高的颜色在混合中占比较大,就像默认情况那样。
以下是常见常数、相关因子及其融合因子结果的详细列表:
| 常数 | 相关因子 | 融合因子结果 |
| ---- | ---- | ---- |
| GL_ZERO | 源因子或目的因子 | (0, 0, 0, 0) |
| GL_ONE | 源因子或目的因子 | (1, 1, 1, 1) |
| GL_DST_COLOR | 源因子 | ($R_d$, $G_d$, $B_d$, $A_d$) |
| GL_SRC_COLOR | 目的因子 | ($R_s$, $G_s$, $B_s$, $A_s$) |
| GL_ONE_MINUS_DST_COLOR | 源因子 | (1, 1, 1, 1) - ($R_d$, $G_d$, $B_d$, $A_d$) |
| GL_ONE_MINUS_SRC_COLOR | 目的因子 | (1, 1, 1, 1) - ($R_s$, $G_s$, $B_s$, $A_s$) |
| GL_SRC_ALPHA | 源因子或目的因子 | ($A_s$, $A_s$, $A_s$, $A_s$) |
| GL_ONE_MINUS_SRC_ALPHA | 源因子或目的因子 | (1, 1, 1, 1) - ($A_s$, $A_s$, $A_s$, $A_s$) |
| GL_DST_ALPHA | 源因子或目的因子 | ($A_d$, $A_d$, $A_d$, $A_d$) |
| GL_ONE_MINUS_DST_ALPHA | 源因子或目的因子 | (1, 1, 1, 1) - ($A_d$, $A_d$, $A_d$, $A_d$) |
| GL_SRC_ALPHA_SATURATE | 源因子 | ($f$, $f$, $f$, 1); 其中 $f = \min(A_s, 1 - A_d)$ |