灰度滤镜
1.jpeg一、灰度滤镜原理
1.浮点算法:Gray=R0.3+G0.59+B0.11
2.整数⽅方法:Gray=(R30+G59+B11)/100
3.移位⽅方法:Gray =(R76+G151+B*28)>>8;
4.平均值法:Gray=(R+G+B)/3; 5.仅取绿⾊色:Gray=G;
二、片元着色器代码实现
precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
const highp vec3 W = vec3(0.2125, 0.7154, 0.0721);
void main (void) {
vec4 mask = texture2D(Texture, TextureCoordsVarying);
float luminance = dot(mask.rgb, W);
gl_FragColor = vec4(vec3(luminance), 1.0);
}
旋涡滤镜
3.jpeg一、旋涡滤镜原理
图像漩涡主要是在某个半径范围里,把当前采样点旋转 ⼀定角度,旋转以后当前点的颜色就被旋转后的点的颜色代替,因此整个半径范围里会有旋转的效果。如果旋转的时候旋转⻆度随着当前点离半径的距离递减,整个 图像就会出现漩涡效果。这⾥使⽤的了了抛物线递减因子:(1.0-(r/Radius)*(r/Radius))。
二、片元着色器代码实现
precision mediump float;
const float PI = 3.14159265;
uniform sampler2D Texture;
const float uD = 80.0;
const float uR = 0.5;
varying vec2 TextureCoordsVarying;
void main()
{
ivec2 ires = ivec2(512, 512);
float Res = float(ires.s);
vec2 st = TextureCoordsVarying;
float Radius = Res * uR;
vec2 xy = Res * st;
vec2 dxy = xy - vec2(Res/2., Res/2.);
float r = length(dxy);
//(1.0 - r/Radius);
float beta = atan(dxy.y, dxy.x) + radians(uD) * 2.0 * (-(r/Radius)*(r/Radius) + 1.0);
vec2 xy1 = xy;
if(r<=Radius)
{
xy1 = Res/2. + r*vec2(cos(beta), sin(beta));
}
st = xy1/Res;
vec3 irgb = texture2D(Texture, st).rgb;
gl_FragColor = vec4( irgb, 1.0 );
}
马赛克滤镜
4.jpeg一、马赛克滤镜原理
⻢赛克效果就是把图⽚的⼀个相当⼤小的区域用同⼀个点的颜色来表示.可以认为是⼤大规模的降低图像的分辨 率,⽽而让图像的⼀一些细节隐藏起来。
二、片元着色器代码实现
precision mediump float;
varying vec2 TextureCoordsVarying;
uniform sampler2D Texture;
const vec2 TexSize = vec2(400.0, 400.0);
const vec2 mosaicSize = vec2(16.0, 16.0);
void main()
{
vec2 intXY = vec2(TextureCoordsVarying.x*TexSize.x, TextureCoordsVarying.y*TexSize.y);
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, UVMosaic);
gl_FragColor = color;
}
六边形马赛克
5.jpeg一、六边形马赛克原理
思路: 我们要做的效果就是让一张图片,分割成由六边形组成,让每 个六边形中的颜色相同(直接取六边形中⼼点像素RGB较⽅便,我们这里采⽤的就是这种⽅法)
将它进行分割,取每个六边形的中⼼点画出一个矩阵,如下:
如上图,画出很多长和宽⽐例为 3:√3
的的矩形阵。然后我们可以 对每个点进⾏编号,如上图中,采⽤坐标系标记.
假如我们的屏幕的左上点为上图的(0,0)
点,则屏幕上的任⼀点我们找到它所对应的那个矩形了了。
假定我们设定的矩阵⽐例为 3*LEN : √3*LEN
,那么屏幕上的任意 点(x, y)所对应的矩阵坐标为(int(x/(3*LEN)), int(y/ (√3*LEN)))
。
wx,wy -> 表示纹理坐标在所对应的矩阵坐标为:
int wx = int(x /( 1.5 * length));
int wy = int(y /(√3/2.0 * length));
二、片元着色器源码
precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
const float mosaicSize = 0.03;
void main (void)
{
float length = mosaicSize;
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);
vec2 v1, v2, vn;
if (wx/2 * 2 == wx) {
if (wy/2 * 2 == wy) {
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 {
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) {
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 {
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;
}
网友评论