在 GMS2 中实现动态遮罩效果(译)

作者:顺子
2017-11-11
26 25 2
这是翻译的 YoYo 官方博客里的一篇教程——DYNAMIC RENDERING MASKS

这是一篇小教程,内容不多,但是效果很酷而且十分实用。当我们在屏幕上绘制内容时,大多数人都只考虑颜色,即红、绿、蓝三个颜色通道,但其实还有一个 Alpha 通道,但如果你想要借此来构建精灵或处理画面上的内容时可能会遇到很多问题,但是有一件事用 Alpha 通道绝对合适,那就是制作蒙板遮罩。

因为玩家只会看到处理过的最终结果画面,所以我们可以使用 Alpha 通道来处理画面以获取我们想要的效果。首先我们要知道有这样一个命令——“gpu_set_colorwriteenable()”——这个方法可以用来打开或关闭颜色和 Alpha 通道是否允许写入。

首先,我们在屏幕上取任意像素点,每个像素点都具有4个通道——红、绿、蓝以及 Alpha,你可以任意启用或关闭其中的任何通道。然后我们要定义一个“特殊”的遮罩,然后把精灵图像写入这个“特殊”的遮罩。这样一来这个 RGB 通道就会变成这个样子——比如说,一个有趣的按钮,我们可以正常渲染这个按钮图像,然后我们用屏幕上的 Alpha 通道来“遮”住按钮外面的内容,这样我们就只绘制按钮内部的画面了。

我们现创建两个精灵,一个按钮,以及一个我们希望绘制的“遮罩”的造型精灵。

现在我们的思路是这样的,我们先按照常规的方式把所有内容绘制出来,包括背景、按钮以及按钮的阴影等等,然后要来限制整个按钮绿色区域内部的内容。当然要实现这个目标也有很多其他的方法,比如使用着色器等等,但哪些方法更复杂。接下来我们还要准备一个背景和用来绘制按钮的精灵。

一切准备就绪,如果我们此时来创建测试对象和绘制事件,我们只需要按部就班,首先是背景,接着是按钮阴影,最后是按钮本身,一切照旧。

draw_sprite(sBackground,0, 0,0);
draw_sprite_ext(sButton,0, 32+4,32+4,1,1,0,c_black,0.5);
draw_sprite(sButton,0, 32,32);

接下来的操作才是重点!我们要禁用所有的颜色通道和混合模式,然后在 alpha 通道写入“0”,如果混合模式是开启状态,这个0会被混合模式按正常的数值进行处理(即完全透明)就不会被正确写入——或者说不是我们希望的样子。而关闭混合模式以后,0就可以被写入 alpha 通道,而此时其他颜色通道中的图像则不会受影响。

gpu_set_blendenable(false)
gpu_set_colorwriteenable(false,false,false,true);
draw_set_alpha(0);
draw_rectangle(0,0, room_width,room_height, false);

如上,我们禁用了混合模式和颜色通道,并将 alpha 设置为0,然后绘制了一个全屏的矩形——当然这个矩形只会填充 alpha 通道。接下来,我们要来实现“遮罩”,遮罩即整个屏幕内我们希望展示的区域。这可以是任何形状或区域,不过在本文中,特制按钮中的绿色区域。

draw_set_alpha(1);
draw_sprite(sMask,0, 32,32);
gpu_set_blendenable(true);
gpu_set_colorwriteenable(true,true,true,true);

这里我们把 alpha 值设回了1,并且绘制了“sMask”这个遮罩精灵——同样是关闭了混合模式的,因此。

现在我们画面上是这样的:正常的背景画面上有一个按钮,然后上面被一个 alpha 值是0的矩形覆盖,但按钮的绿色区域哪一块的 alpha 值是1。接下来我们要打开 alpha 模式,但并不是读取精灵的 alpha 通道,而是去读取整个屏幕画面的 alpha 通道。因为精灵中并没有 alpha 值因此我们需要打开 alphatest 模式,这样会尝试从精灵中读取 alpha 值,然后在最后要记得再把这个测试模式关闭。

gpu_set_blendmode_ext(bm_dest_alpha,bm_inv_dest_alpha);
gpu_set_alphatestenable(true);
draw_sprite(sPlayer,0, mouse_x,mouse_y);
gpu_set_alphatestenable(false);
gpu_set_blendmode(bm_normal);

然后最后我们再把混合模式设置好,启用 alpha 通道来进行测试,然后我们设置以鼠标所在位置来绘制这个精灵,把所有的设置恢复到正常模式。最后我们点击运行,就会看到以下画面。

我们可以用类似的机制去实现许多类似上图的效果,比如高亮标记游戏中的一些元素等。甚至可以用来实现水的效果。

最后两段因为跟教程没什么关系就不翻了,不过这个教程确实蛮有意思,我尝试了一个移动遮罩的效果,感觉如果在一些解谜游戏中使用也是蛮有趣的。

本文为用户投稿,不代表 indienova 观点。

近期点赞的会员

 分享这篇文章

顺子 

https://www.gamebar.me/ 

您可能还会对这些文章感兴趣

参与此文章的讨论

  1. 积极而小米 2018-03-27

    这个666啊,可以用来做滑动面板。不知道gms有没有这功能

  2. 吴会赛 2018-07-31

    效果很6,不过完全看不懂啥意思,可能我不太懂中文

您需要登录或者注册后才能发表评论

登录/注册