OpenGLSL初探(六)使用GLSL实现滤镜之灰度滤镜、正方形马赛克滤镜、六边形马赛克滤镜和三角形马赛克滤镜

这篇博客详细介绍了如何使用GLSL实现四种滤镜效果:灰度滤镜、正方形马赛克滤镜、六边形马赛克滤镜和三角形马赛克滤镜。主要通过修改片元着色器代码来实现,涉及浮点算法、马赛克效果的原理以及不同形状的分割方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

此博客只为记录滤镜的算法,所以修改的只是片元着色器代码
注:具体代码请查看上一篇博客:https://blog.youkuaiyun.com/weixin_40918107/article/details/107748865

1. 准备工作

  • 创建顶点着色器和片元着色器
  • 加载着色器,并链接
  • 创建图层和上下文
  • 清空缓冲区,并设置渲染缓冲区与帧缓冲区
  • 开始绘制

2.滤镜的实现

图片无滤镜正常显示的顶点着色器和片元着色器代码。
注:以下代码中的中文注释在复制代码时,请删除,否则会有未知的错误
顶点着色器:

//顶点坐标
attribute vec4 Position;
//纹理坐标
attribute vec2 TextureCoords;
//需要传入片元着色器的纹理坐标
varying vec2 TextureCoordsVarying;

void main (void) {
   
    gl_Position = Position;
    TextureCoordsVarying = TextureCoords;
}

片元着色器:

//声明高精度float
precision highp float;
//纹理
uniform sampler2D Texture;
//纹理坐标
varying vec2 TextureCoordsVarying;

void main (void) {
   
    vec4 mask = texture2D(Texture, TextureCoordsVarying);
    gl_FragColor = vec4(mask.rgb, 1.0);
}

2.1灰度滤镜

灰度滤镜实现的方案:

  • 浮点算法:Gray=R0.3+G0.59+B*0.11
  • 整数⽅法:Gray=(R30+G59+B*11)/100
  • 移位⽅法:Gray =(R76+G151+B*28)>>8;
  • 平均值法:Gray=(R+G+B)/3;
  • 只取绿色:Gray=G;

一般使用第一个方案:浮点算法。
实现灰度滤镜只需要修改片元着色器即可,顶点着色器不变。

precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
//变换因子,即上方的浮点算法,此值取自GPUImage源码
const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);

void main (void) {
   
    //获取对于纹理坐标下的颜⾊值
    vec4 mask = texture2D(Texture, TextureCoordsVarying);
    //将颜⾊mask 与 变换因⼦点乘得到灰度值.由向量转变成标量
    float luminance = dot(mask.rgb, W);
    //vec4、vec3是内建函数,vec3是将颜色值RGB都设置成luminance
    gl_FragColor = vec4(vec3(luminance), 1.0);
}

2.2 正方形马赛克滤镜

⻢赛克效果就是把图⽚的⼀个相当⼤⼩的区域⽤同⼀个点的颜⾊来表示.可以认为是⼤规模的降低图像的分辨率,⽽让图像的⼀些细节隐藏起来。其实与临近过滤非常的相似。
马赛克效果是不可逆的,因为这是把原图给修改了。

片元着色器代码:

precision mediump float;
//纹理坐标
varying vec2 TextureCoordsVarying;
//纹理采样器
uniform sampler2D Texture;
//纹理图⽚size
const vec2 TexSize = vec2(400.0, 400.0);
//⻢赛克Size
const vec2 mosaicSize = vec2(16.0, 16.0);
void main()
{
   
 //计算实际图像位置 
 vec2 intXY = vec2(TextureCoordsVarying.x*TexSize.x, TextureCoordsVarying.y*TexSize.y);
 
 // floor (x) 内建函数,返回⼩于/等于X的最⼤整数值,向下取整
 // floor (intXY.x / mosaicSize.x) * mosaicSize.x 计算出⼀个⼩于⻢赛克的坐标.
 vec2 XYMosaic = vec2(floor(intXY.x/mosaicSize.x)*mosaicSize.x, floor(intXY.y/
mosaicSize.y)*mosaicSize.y);
 
 //换算回纹理坐标
 vec2 UVMosaic = vec2(XYMosaic.x/TexSize.x, XYMosaic.y/TexSize.y);
 //获取到⻢赛克后的纹理坐标的颜⾊值
 vec4 color = texture2D(Texture
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值