GameMaker8.0 :新手教程 Part 22 -混色-

分类栏目:gamemaker教程

616

GameMaker8.0 :新手教程 Part 22 -混色-

1、颜色的混合

细心的GMer可能已经发现,在GM8的图像编辑器中,有“颜色模式”一选项,可选择“混合”或是“替换”。
GameMaker8.0 :新手教程 Part 22 -混色-
当选择颜色的透明度为255时,“混合”和“替换”是没有区别的,都是用新的颜色取代旧的颜色。
但是如果新颜色的透明度不是255,而是半透明,比如120,那么“混合”模式下,会将新颜色与原本的颜色进行混合,比如要画上去的颜色是(0, 0, 255, 120)(请参考第十章RGBA相关信息),原本的颜色是(255, 0, 0, 120),那么混合之后的颜色是(87, 0, 167, 183)。
这个混合是如何计算得到的呢?
首先,我们要把所有值压缩到0~1之间,也就是说让所有值都除以255,例如上述的(0, 0, 255, 120)压缩为(0, 0, 1, 0.47),(255, 0, 0, 120)压缩为(1, 0, 0, 0.47),(87, 0, 167, 183)压缩为(0.34, 0, 0.65, 0.72)。
然后,我们要规定一下符号,s代表source,即你要画上去的颜色,d代表destanition,即原本的颜色,o代表output,最终得到的颜色,R代表Red,G代表Green,B代表Blue,A代表Alpha。将一个大写字母和一个小写字母组合,如Rs,代表要画上去的颜色的Red的值。为了更好的理解,我们将上面举的例子用符号来表示出来:
Rd = 1, Gd = 0, Bd = 0, Ad = 0.47,
Rs = 0, Gs = 0, Bs = 0.47, As = 0.47,
Ro = 0.34, Go = 0, Bo = 0.65, Ao = 0.72。

请一定要记住这十二个符号每一个所代表的含义,因为我们后面都将用这十二个符号来讲解混色。
最后,查询wiki百科得知,GM的图像编辑器所使用的混色计算方式为:
Ao = As + Ad * (1 - As)
Ro = (Rs * As + Rd * Ad * (1 - As)) / Ao
Go = (Gs * As + Gd * Ad * (1 - As)) / Ao
Bo = (Bs * As + Bd * Ad * (1 - As)) / Ao

可以自己动手做做实验,看看是不是这样。

2、混合因素

混色的计算方式可以有很多种,并非只有上面所讲的那种。只要输入一个source,一个destination,经过一定的计算得到output的过程,都可以称之为混色。
事实上,所有的混色计算都可以总结为下面一个公式:
Ro = Rs * a1 + Rd * b1
Go = Gs * a2 + Gd * b2
Bo = Bs * a3 + Bd * b3
Ao = As * a4 + Ad * b4

在这之中,(a1, a2, a3, a4)和(b1, b2, b3, b4)就是两个混合因素(factor),(a1, a2, a3, a4)称为source的混合因素,(b1, b2, b3, b4)称为destination的混合因素。注意,如果计算的值大于1,则视为1。
同样是拿GM的图像编辑器举例子,它的两个混合因素分别是(As / Ao, As / Ao, As / Ao, 1)和(Ad * (1 - As) / Ao, Ad * (1 - As) / Ao, Ad * (1 - As) / Ao, 1 - As)。注意,这个混合因素是很特别的,它无法用代码来实现。
GM所提供的混合因素有:
bm_zero: 混合因素是 (0, 0, 0, 0)
bm_one: 混合因素是 (1, 1, 1, 1)
bm_src_color: 混合因素是 (Rs, Gs, Bs, As)
bm_inv_src_color: 混合因素是 (1 – Rs, 1 – Gs, 1 – Bs, 1 – As)
bm_src_alpha: 混合因素是 (As, As, As, As)
bm_inv_src_alpha: 混合因素是 (1 – As, 1 – As, 1 – As, 1 – As)
bm_dest_alpha: 混合因素是 (Ad, Ad, Ad, Ad)
bm_inv_dest_alpha: 混合因素是 (1 – Ad, 1 – Ad, 1 – Ad, 1 – Ad)
bm_dest_color: 混合因素是 (Rd, Gd, Bd, Ad)
bm_inv_dest_color: 混合因素是 (1 – Rd, 1 – Gd, 1 – Bd, 1 – Ad)
bm_src_alpha_sat: 混合因素是 (f, f, f, 1); 其中f = min(As, 1 – Ad)
注意:虽然有些因素的名字带了src或者dest,但是这并不意味着只有source能使用src因素或者只有destination能使用dest因素,所有因素都是source和destination共用的。

3、设置混色模式

draw_set_blend_mode_ext(src, dest) 这个函数用来设置混色模式。参数src填写source的混合因素,参数dest填写destination的混合因素。
注意,这是一个全局设置,一旦启用,整个游戏都会使用这个混色模式,所以在使用完,请恢复混色模式到默认状态,默认状态的混合因素为draw_set_blend_mode_ext(bm_src_alpha, bm_inv_src_alpha);,你也可以使用draw_set_blend_mode(bm_normal);,两个代码等效。
注意:由于GM8的窗口并不是半透明的,因此,如果你在屏幕上进行混色绘制时,得到的Ao往往会被忽略,而强制设置为1。但是,如果你是在表面(surface)上进行混色绘制,则会保留Ao。
draw_set_blend_mode(mode) 这个函数是上面这个函数的简化版,参数只能选填bm_mormal,bm_add,bm_subtract, bm_max四个参数。这是GM8提供的四种比较常用的混合因素组合方式,你可以完全使用draw_set_blend_mode_ext来代替。
bm_mormal对应(bm_src_alpha, bm_inv_src_alpha)
bm_add对应(bm_src_alpha, bm_one)
bm_subtract对应(bm_zero, bm_inv_src_color)
bm_max对应(bm_src_alpha, bm_inv_src_color)
bm_normal就是正常的混色方案,当不设置混色模式时GM8的默认混合因素。
bm_add是对颜色的叠加,瞎眼特效必备。
在制作弹幕游戏的时候,给弹幕用上bm_add,就能让弹幕看起来非常炫丽。(只适用于黑色或偏暗的背景色)
在用圆球spr组成文字的时候,bm_add能消除圆球spr的重叠,视觉效果更好。
总之,bm_add是混色中最常用的一种模式,经常活跃在各种特效之中。
例如:https://www.bilibili.com/video/av3877543/
bm_subtract多用于表面(surface)之中,可以在表面上“挖洞”,下一章就会了解到。
bm_max和bm_add效果比较接近,混合因素略有不同,destination的权重相比bm_add要更低,因此可以用来去除黑色底色。
假设你有一张素材图,但是他有黑色底色难以去除
GameMaker8.0 :新手教程 Part 22 -混色-
事实上,你无需去除它的黑色底色,直接导入GM8中,假设精灵名为sprFire,绘制它时在draw事件内写:
draw_set_blend_mode(bm_max);
draw_sprite(sprFire, 0, x, y);
draw_set_blend_mode(bm_normal);
bm_max的混色会自动帮你去除黑色底色:
GameMaker8.0 :新手教程 Part 22 -混色-
举例:区域反色效果
draw_set_blend_mode_ext(bm_inv_dest_color, bm_zero);
draw_set_color(c_white);
draw_set_alpha(1);
draw_rectangle(200, 200, 400, 400, false);//这里可以改成绘制任何纯白色图案或精灵
draw_set_blend_mode(bm_normal);
效果如下:
GameMaker8.0 :新手教程 Part 22 -混色-
很容易推出,反色就是:
Ro = 1 - Rd, Go = 1 - Gd,Bo = 1 - Bd。由于屏幕上透明度强制为1,所以Ao的值可以不考虑。
因此,我们设置混合因素:source为bm_inv_dest_color,即(1 – Rd, 1 – Gd, 1 – Bd, 1 – Ad),dest为bm_zero,即(0, 0, 0, 0),然后再绘制上纯白色的图案,由于纯白色就是(1, 1, 1, 1),所以Rs,Gs,Bs,As均为1,带入方程中就可以解出:
Ro = 1 * (1 - Rd) + Rd * 0 = 1 - Rd。Go和Bo同理。
上面说过,由于GM8的窗口不能半透明,所以实际上Ao总是强制设置为1,因此,直接使用混色能实现的功能比较有限。要想真正发挥混色的能力,那么就要用到可以储存Ao值的表面(surface),表面就是我们下一章所要的内容。可以说,表面+混色是GM8高端特效的绝对主力,在GMS1/2中则引入了更加高端的shader(同时也更加复杂难懂)来实现特效。

4、绘制函数中的混色

有些绘制函数中有混色的参数,例如:
draw_sprite_ext(sprite, subimg, x, y, xscale, yscale, rot, color, alpha)中的color参数,再比如draw_sprite_general(sprite, subimg, left, top, width, height, x, y, xscale, yscale, rot, c1, c2, c3, c4, alpha)提供了c1~c4四个参数,代表左上角,右上角,右下角,左下角的渐变混色。
这种混色模式的因素为(bm_dest_color, bm_zero),或者(bm_zero, bm_src_color),两种混色模式的效果是相同的。
混色结果为:
Ro = Rs * Rd
Go = Gs * Gd
Bo = Bs * Bd
Ao = As * Ad(实际上强制设置为1)