持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情
之前的文章中,我们使用 GLSL 自定义着色器 完成加载显示 一张图片,之后 实现了 二分屏、三分屏、四分屏、六分屏和九分屏这些 简单的滤镜效果。 今天我们来 实现一下 灰度滤镜效果。
首先我们先从 灰度滤镜的概念开始吧:
中性灰度滤镜
中性灰度滤镜(Neutral density filter), 简称“中灰镜”或ND镜 是一种无色至灰色的摄影滤镜。理想中的中灰镜可以减弱所有波长的光的亮度,而不会发生偏色。中灰镜的用处在于于各种环境下(特别是光照强烈时)能让摄影师更好的控制快门速度和光圈大小来达到某些特殊效果,同时又不会因为快门速度过慢而导致过曝。
滤镜含义
滤镜主要是用来实现图像的各种特殊效果。它在Photoshop中具有非常神奇的作用。所以有的Photoshop都按分类放置在菜单中,使用时只需要从该菜单中执行这命令即可。滤镜的操作是非常简单的,但是真正用起来却很难恰到好处。滤镜通常需要同通道、图层等联合使用,才能取得最佳艺术效果。如果想在最适当的时候应用滤镜到最适当是位置,除了平常的美术功底之外,还需要用户的滤镜的熟悉和操控能力,甚至需要具有很丰富的想象力。这样,才能有的放矢的应用滤镜,发挥出艺术才华。
颜色通道
-
保存图像颜色信息的通道
-
每个图像都有一个或多个颜色通道,图像中默认的颜色通道数取决于其颜色模式,即一个图像的颜色模式将决定其颜色通道的数量。例如,CMYK图像默认有4个通道,分别为青色、洋红、黄色、黑色。在默认情况下,位图模式、灰度、双色调和图像只有一个通道。RGB和Lab图像有3个通道,CMYK图像有4个通道。
-
每个颜色通道都存放着图像中颜色元素的信息。所有颜色通道中的颜色叠加混合产生图像中像素的颜色。
-
为了便于理解通道的概念,我们以RGB模式图像为例,简单介绍颜色通道原理。如下图:
-
我们知道,一幅图像的基本组成单位是以RGB为基础展开的,为此可以理解为一个图像由RGB这样的三个元素组成,R为一个红色通道,表示为1;G为一个绿色通道,表示为2;B 为一个蓝色通道,表示为3;有一处白色图像则为4,它是由1、2、3处的通道颜色混合而成,这相当于我们使用的调色板,几种颜色混合在一起将产生一种新的颜色。
有5种方法来实现灰度滤镜的算法(前三种方法是利用权重来实现的):
- 浮点算法: Gray = R * 0.2125 + G * 0.7154 + B * 0.0721 (根据对应纹素的颜色值调整RGB的比例)
- 整数算法: Gray = (R * 30 + G * 59 + B * 11) / 100 (同浮点算法)
- 移位算法: Gray = (R * 76 + G * 151 + B * 28) >> 8
- 平均值法: Gray = (R + G + B) / 3; (获取到对应纹素的RGB平均值,填充到三个通道上面)
- 仅取绿色: Gray = G (一个颜色填充三个通道)
实现片元着色器
因为我们之前实现了滤镜加载显示的逻辑,所以现在我们只需要重新定义一个片元着色器文件 fsh 文件即可
precision highp float;
varying highp vec2 varyTextCoord;
uniform sampler2D colorMap;
const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);
void main()
{
vec4 mask = texture2D(colorMap, varyTextCoord);
float luminance = dot(mask.rgb, W);
gl_FragColor = vec4(vec3(luminance), 1.0);
}
好了,看下我们的滤镜效果: