关于前端:WebGL-系列-09-图像过滤器

3次阅读

共计 2302 个字符,预计需要花费 6 分钟才能阅读完成。

  • 原文地址:Day 9. Image filters
  • 原文作者:Andrei Lesnitsky

这是 WebGL 系列的第 9 天教程,每天都有新文章公布。

订阅或者退出邮件列表以便及时获取更新内容。

源代码在这里

第 8 天咱们学习了如何在 webgl 中应用纹理,接下来让咱们利用这些常识来构建乏味的货色。

明天,咱们将探讨如何实现简略的图像过滤器。

反转色彩

咱们要做的第一个最简略的图像过滤器,就是对图像的所有色彩反转的滤镜。

咱们如何反转色彩?

原始值是在 [0..1] 范畴内。

如果咱们从每个重量中减去 1,咱们将失去负值,glsl 中就有一个 abs 函数。

您还能够像在 C/C++ 中一样,在 glsl 中定义除 void main 外的其它函数,因而让咱们创立 inverse 函数。

???? src/shaders/texture.f.glsl


 uniform sampler2D texture;

 uniform vec2 resolution;

+ vec4 inverse(vec4 color) {+     return abs(vec4(color.rgb - 1.0, color.a));

+ }

+ 

 void main() {

 vec2 texCoord = gl_FragCoord.xy / resolution;

 gl_FragColor = texture2D(texture, texCoord);

  

让咱们中真正地应用它:

???? src/shaders/texture.f.glsl


 void main() {

 vec2 texCoord = gl_FragCoord.xy / resolution;

 gl_FragColor = texture2D(texture, texCoord);

+ 

+     gl_FragColor = inverse(gl_FragColor);

 }

  

瞧,咱们有一个只有 4 行代码的逆滤波器。

黑白滤镜

让咱们考虑一下如何实现黑白滤镜。

红色是 vec4(1, 1, 1, 1)

彩色是 vec4(0, 0, 0, 1)

什么是灰色暗影?显然,咱们须要为每个色彩重量增加雷同的值。

因而,基本上咱们须要计算每个组件的“亮度”值。在很毛糙的实现办法中,咱们能够将所有色彩重量相加并除以 3(算术平均值)。

留神:这不是最好的办法,因为不同的色彩会给出雷同的后果(例如 vec3(0.5, 0, 0)vec3(0, 0.5, 0),但实际上这些色彩具备不同的“亮度”,我只是想让这些例子通俗易懂)。

好吧,让咱们尝试实现这个:

???? src/shaders/texture.f.glsl


 return abs(vec4(color.rgb - 1.0, color.a));

 }

+ vec4 blackAndWhite(vec4 color) {+     return vec4(vec3(1.0, 1.0, 1.0) * (color.r + color.g + color.b) / 3.0, color.a);

+ }

+ 

 void main() {

 vec2 texCoord = gl_FragCoord.xy / resolution;

 gl_FragColor = texture2D(texture, texCoord);

-     gl_FragColor = inverse(gl_FragColor);

+     gl_FragColor = blackAndWhite(gl_FragColor);

 }

  

哇!看起来不错。

棕褐色滤镜

好的,接下来是能做出带有奇异成果“老式”照片的棕褐色滤镜。

棕褐色为红褐色,RGB 值是 112, 66, 20

让咱们定义 sepia 函数和和色彩:

???? src/shaders/texture.f.glsl


 return vec4(vec3(1.0, 1.0, 1.0) * (color.r + color.g + color.b) / 3.0, color.a);

 }

+ vec4 sepia(vec4 color) {+     vec3 sepiaColor = vec3(112, 66, 20) / 255.0;

+ }

+ 

 void main() {

 vec2 texCoord = gl_FragCoord.xy / resolution;

 gl_FragColor = texture2D(texture, texCoord);

  

有个毛糙的实现办法,是将肯定比例的棕褐色混入原始色彩。有一个 mix 函数:

???? src/shaders/texture.f.glsl


 vec4 sepia(vec4 color) {vec3 sepiaColor = vec3(112, 66, 20) / 255.0;

+     return vec4(+         mix(color.rgb, sepiaColor, 0.4),

+         color.a

+     );

 }

 void main() {

 vec2 texCoord = gl_FragCoord.xy / resolution;

 gl_FragColor = texture2D(texture, texCoord);

-     gl_FragColor = blackAndWhite(gl_FragColor);

+     gl_FragColor = sepia(gl_FragColor);

 }

  

后果:

这应该使您更好地理解如何在片段着色器中执行操作。

尝试实现其余一些过滤器,例如饱和度或活力度过滤器。

今天见????

正文完
 0