在 Egret Engine 3.1.0 开始提供 WebGL 渲染的颜色矩阵滤镜和模糊滤镜。颜色矩阵滤镜在游戏中常用来在战斗中将“怪物”“灰掉”等功能。模糊滤镜可以实现显示对象的模糊效果。
需要注意的是 Web 下的 Canvas 模式和 Native 下暂不支持滤镜功能。
通过显示对象的 filters 属性设置显示对象关联的每个滤镜对象的索引数组。下面使用 Bitmap 为例,其他显示对象也支持 filters 属性。
颜色矩阵滤镜
ColorMatrixFilter–颜色矩阵滤镜(egret.ColorMatrixFilter) 在颗粒等级上提供给你更好的控制显示对象的颜色转换。ColorMatrixFilter为 4行5列的多维矩阵(20个元素的数组)。下图为等效的矩阵。
使用颜色转换滤镜
在 Egret 中使用颜色转换矩阵比较简单,先看一段实现图片变“灰”效果的代码,然后详细介绍。首先是一张准备好的图片:
然后我们通过下面颜色转换矩阵代码添加一个变“灰”的效果:
var hero:egret.Bitmap = new egret.Bitmap();
hero.texture = RES.getRes("hero_png");
this.addChild(hero);
//颜色矩阵数组
var colorMatrix = [
0.3,0.6,0,0,0,
0.3,0.6,0,0,0,
0.3,0.6,0,0,0,
0,0,0,1,0
];
var colorFlilter = new egret.ColorMatrixFilter(colorMatrix);
hero.filters = [colorFlilter];
效果如下:
首先我们新建了一个显示对象,然后新建了一个颜色转换矩阵 ColorMatrixFilter
,并通过显示对象的 filters
属性来设置滤镜。显示对象的 filters
属性包含当前与显示对象关联的每个滤镜对象的索引数组。
在 Egret 中使用滤镜功能还是很方便的,实现效果的关键主要是颜色转换矩阵的设置。上面我们将每个颜色通道都乘相同的系数来实现灰度效果。
通过 ColorMatrixFilter 的 matrix 属性可以设置颜色矩阵。需要注意的是不能直接通过
colorFlilter.matrix[4] = 100;
这样的方式直接修改颜色矩阵。只能通过获得数组的引用然后修改,最后重置重置矩阵:
//获得数组。
var test = colorFlilter.matrix;
//修改数组中的值。
test[4] = 100;
//重置矩阵。
colorFlilter.matrix = test;
颜色矩阵
在上面例子中我们实现了灰度图的效果,再来看一下颜色矩阵的含义:
实际的颜色值由下面的公式决定:
redResult = (a[0] * srcR) + (a[1] * srcG) + (a[2] * srcB) + (a[3] * srcA) + a[4];
greenResult = (a[5] * srcR) + (a[6] * srcG) + (a[7] * srcB) + (a[8] * srcA) + a[9];
blueResult = (a[10] * srcR) + (a[11] * srcG) + (a[12] * srcB) + (a[13] * srcA) + a[14];
alphaResult = (a[15] * srcR) + (a[16] * srcG) + (a[17] * srcB) + (a[18] * srcA) + a[19];
公式中 srcR、srcG、srcB、srcA 表示原始显示对象的像素值, a 即我们设置的颜色矩阵的数组。我们得到的红绿蓝和alpha通道实际由颜色矩阵和原始图片的像素值同时决定。颜色矩阵中的 Off 可以直接设置偏移量加上相应的 R G B A 的值的乘积即为最终的颜色值。所以与原来完全相同的矩阵转换应该是下面这样的:
var colorMatrix = [
1,0,0,0,0,
0,1,0,0,0,
0,0,1,0,0,
0,0,0,1,0
];
设置红色偏移量
在颜色矩阵中直接设置每一行中最后一个值即可设置偏移量,我们直接设置一下红色通道的偏移量,结果整张图片将变红。
var colorMatrix = [
1,0,0,0,100,
0,1,0,0,0,
0,0,1,0,0,
0,0,0,1,0
];
修改代码中的颜色矩阵数组,编译运行得到如下效果图:
需要注意的 R G B 通道对应的偏移量的值应该为 -255 ~ 255,Alpha 通道对应的偏移量取值范围为 0 ~ 1.应避免传入除数字外其他类型的值,比如字符串等。
绿色加倍
如果想使绿色通道加倍,colorMatrix[6] 加倍即可:
var colorMatrix = [
1,0,0,0,0,
0,2,0,0,0,
0,0,1,0,0,
0,0,0,1,0
];
红色决定蓝色值
如果你要使结果图像中的蓝色与原图的红色数量相等,将colorMatrix[10]设为1, colorMatrix[12]设为0 ,即结果的蓝色值完全由原始的红色值决定:
var colorMatrix = [
1,0,0,0,0,
0,1,0,0,0,
1,0,0,0,0,
0,0,0,1,0
];
增加亮度
增加亮度的最简单途径是给每个颜色值添加相同的偏移量。
var colorMatrix = [
1,0,0,0,100,
0,1,0,0,100,
0,0,1,0,100,
0,0,0,1,0
];
通过”颜色矩阵滤镜”你可以完成除了亮度和灰度之外复杂的颜色调整,如调整对比度,饱和度和色相等。
模糊滤镜
在 Egret 中使用模糊滤镜也比较简单,通过 BlurFilter 类来设置模糊滤镜。
var hero:egret.Bitmap = new egret.Bitmap();
hero.texture = RES.getRes("hero_png");
this.addChild(hero);
var blurFliter = new egret.BlurFilter( 1 , 1);
hero.filters = [blurFliter];
和颜色转换矩阵类似,实例化一个 BlurFilter 并将其保存到显示对象的 filters 属性中即可。其中示例化 BlurFilter 有两个参数,即为 x 、y 方向的模糊度。
值越大效果越模糊。
需要注意的是模糊滤镜对性能的消耗比较大,应谨慎使用。普通显示对象可以开启 cacheAsBitmap 提高一些性能。
显示对象的 filters 属性可以保存多个滤镜效果,比如同时使用hero.filters = [blurFliter,colorFlilter];
模糊和颜色矩阵滤镜效果。多个效果同时生效。