前提: 使用GLSL实现滤镜的前提条件是可以用GLSL显示普通图片算法
灰度滤镜bash
算法ui
片元着色器代码实现:spa
precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
//灰度计算比率 (借用GPUImage的值)
const highp vec3 ratio = vec3(0.2125, 0.7154, 0.0721);
void main (void) {
vec4 mask = texture2D(Texture, TextureCoordsVarying);
// Gray值
float luminance = dot(mask.rgb, ratio);
gl_FragColor = vec4(vec3(luminance), 1.0);
}
复制代码
颠倒滤镜3d
片元着色器代码实现:code
precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
void main (void) {
//y轴坐标反转
vec4 color = texture2D(Texture, vec2(TextureCoordsVarying.x, 1.0 - TextureCoordsVarying.y));
gl_FragColor = color;
}
复制代码
旋涡滤镜orm
片元着色器代码实现:cdn
precision mediump float;
uniform sampler2D Texture;
//旋涡旋转角度
const float uD = 80.0;
//旋涡半径,范围(0 ~ 0.5)
const float uR = 0.5;
//纹理坐标
varying vec2 TextureCoordsVarying;
void main()
{
//旋涡半径
float Radius = uR;
//当前纹理坐标
vec2 xy = TextureCoordsVarying;
//当前纹理到中心点的向量
vec2 dxy = xy - vec2(0.5, 0.5);
//当前纹理到中心点距离
float r = length(dxy);
//旋转角度变化
float beta = atan(dxy.y, dxy.x) + radians(uD) * 2.0 * ( 1.0 -(r/Radius)*(r/Radius));
//旋涡范围内的坐标变化
if(r<=Radius)
{
xy = 0.5 + r * vec2(cos(beta), sin(beta));
}
//将旋转的纹理坐标替换原始纹理坐标TextureCoordsVarying 获取对应像素点的颜⾊.
vec3 irgb = texture2D(Texture, xy).rgb;
//将计算后的颜⾊填充到像素点中 gl_FragColor
gl_FragColor = vec4( irgb, 1.0 );
}
复制代码
马赛克滤镜blog
1.矩形马赛克 片元着色器代码实现:图片
precision mediump float;
varying vec2 TextureCoordsVarying;
uniform sampler2D Texture;
//马赛克矩形所占纹理范围比例
const vec2 mosaicSizeRatio = vec2(0.05, 0.05);
void main()
{
//纹理范围能够切割多少个矩形马赛克
vec2 totalXY = vec2(floor(1.0 / mosaicSizeRatio.x), floor(1.0 / mosaicSizeRatio.y));
//当前纹理在哪一个矩形马赛克范围
vec2 eachXY = vec2(floor(TextureCoordsVarying.x / mosaicSizeRatio.x), floor(TextureCoordsVarying.y / mosaicSizeRatio.y));
//当前纹理块对应的纹理坐标
vec2 UVMosaic = vec2(eachXY.x / totalXY.x, eachXY.y / totalXY.y);
vec4 color = texture2D(Texture, UVMosaic);
gl_FragColor = color;
}
复制代码
2.六边形马赛克
(wx, wy) 表示纹理坐标在所对应的矩阵坐标为:
wx = int(x/(a * length))
wy = int(y/(b * length))
根据行和列的奇偶数排列规则,计算一个矩形块内的任意点距离哪一个六边形的距离短,就属于哪一个六边形.
片元着色器代码实现:
precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
/// 马赛克大小比率
const float mosaicSize = 0.05;
void main (void)
{
//马赛克大小比率
float length = mosaicSize;
// 矩形b
float TR = 0.866025;
//当前纹理坐标
float x = TextureCoordsVarying.x;
float y = TextureCoordsVarying.y;
//当前纹理坐标在所对应的矩阵坐标
int wx = int(x / 1.5 / length);
int wy = int(y / TR / length);
//v1, v2为矩形顶点(六边形的中心点)的纹理坐标
vec2 v1, v2, vn;
//排列行,列的奇偶数判断规则
if (wx/2 * 2 == wx) {
if (wy/2 * 2 == wy) {
//(0,0),(1,1)
v1 = vec2(length * 1.5 * float(wx), length * TR * float(wy));
v2 = vec2(length * 1.5 * float(wx + 1), length * TR * float(wy + 1));
} else {
//(0,1),(1,0)
v1 = vec2(length * 1.5 * float(wx), length * TR * float(wy + 1));
v2 = vec2(length * 1.5 * float(wx + 1), length * TR * float(wy));
}
}else {
if (wy/2 * 2 == wy) {
//(0,1),(1,0)
v1 = vec2(length * 1.5 * float(wx), length * TR * float(wy + 1));
v2 = vec2(length * 1.5 * float(wx + 1), length * TR * float(wy));
} else {
//(0,0),(1,1)
v1 = vec2(length * 1.5 * float(wx), length * TR * float(wy));
v2 = vec2(length * 1.5 * float(wx + 1), length * TR * float(wy + 1));
}
}
//到当前点的距离
float s1 = sqrt(pow(v1.x - x, 2.0) + pow(v1.y - y, 2.0));
float s2 = sqrt(pow(v2.x - x, 2.0) + pow(v2.y - y, 2.0));
//获取对应的纹理坐标
if (s1 < s2) {
vn = v1;
} else {
vn = v2;
}
vec4 color = texture2D(Texture, vn);
gl_FragColor = color;
}
复制代码