Gray=R*0.3+G*0.59+B*0.11
2.整数⽅方法:Gray=(R*30+G*59+B*11)/100
3.移位⽅方法:Gray =(R*76+G*151+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);
}
复制代码
vec2(TextureCoordsVarying.x, 1.0 - TextureCoordsVarying.y)
precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
void main (void) {
vec4 color = texture2D(Texture, vec2(TextureCoordsVarying.x, 1.0 - TextureCoordsVarying.y));
gl_FragColor = color;
}
复制代码
图像漩涡主要是在某个半径范围里,把当前采样点旋转 必定角度,旋转之后当前点的颜色就被旋转后的点的颜色代替,所以整个半径范围里会有旋转的效果。若是旋转的时候旋转角度随着当前点离半径的距离递减,整个图像就会出现漩涡效果git
atan(dxy.y, dxy.x)
加重旋涡角度:atan(dxy.y ,dxy.x ) + radians(uD) * 2.0
加重旋涡衰减角度:atan(dxy.y ,dxy.x ) + radians(uD) * 2.0 * disValue
precision mediump float; //PI
const float PI = 3.14159265; //纹理采样器
uniform sampler2D Texture; //旋转角度
const float uD = 80.0; //旋涡半径
const float uR = 0.5;
//纹理坐标
varying vec2 TextureCoordsVarying;
void main() {
//旋转正方形范围:[512,512]
ivec2 ires = ivec2(512, 512); //获取旋转的直径
float Res = float(ires.s); //纹理坐标[0,0],[1,0],[0,1],[1,1]...
vec2 st = TextureCoordsVarying; //半径 = 直径 * 0.5;
float Radius = Res * uR;
//准备旋转处理的纹理坐标 = 纹理坐标 * 直径 vec2 xy = Res * st;
//纹理坐标的一半
vec2 dxy = xy - vec2(Res/2., Res/2.);
//r
float r = length(dxy);
//抛物线递减因⼦子:(1.0-(r/Radius)*(r/Radius) )
float beta = atan(dxy.y, dxy.x) + radians(uD) * 2.0 * (1.0-(r/Radius)*(r/Radius));
if(r<=Radius)
{
//获取的纹理坐标旋转beta度.
xy = Res/2.0 + r*vec2(cos(beta), sin(beta));
}
//st = 旋转后的纹理坐标/旋转范围 st = xy/Res;
//将旋转的纹理理坐标替换原始纹理理坐标TextureCoordsVarying 获取对应像素点的颜色. vec3 irgb = texture2D(Texture, st).rgb;
//将计算后的颜色填充到像素点中 gl_FragColor
gl_FragColor = vec4( irgb, 1.0 );
}
复制代码
⻢赛克效果就是把图片的⼀个至关大小的区域用同⼀个点的颜色来表示.能够认为是大规模的下降图像的分辨率,而让图像的⼀些细节隐藏起来。github
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, UVMosaic);
//将马赛克颜色值赋值给
gl_FragColor. gl_FragColor = color;
}
复制代码
咱们要作的效果就是让一张图片,分割成由六边形组成,让每一个六边形中的颜色相同(直接取六边形中心点像素RGB较方便)算法
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) {
//(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;
}
复制代码
三角形马赛克的原理相似六边形马赛克原理,只不过是将六边形各边和中心点组成六个三角形bash
precision highp float;
uniform sampler2D Texture;
varying vec2 TextureCoordsVarying;
float mosaicSize = 0.03;
void main (void){
const float TR = 0.866025;
const float PI6 = 0.523599;
float x = TextureCoordsVarying.x;
float y = TextureCoordsVarying.y;
int wx = int(x/(1.5 * mosaicSize));
int wy = int(y/(TR * mosaicSize));
vec2 v1, v2, vn;
if (wx / 2 * 2 == wx) {
if (wy/2 * 2 == wy) {
v1 = vec2(mosaicSize * 1.5 * float(wx), mosaicSize * TR * float(wy));
v2 = vec2(mosaicSize * 1.5 * float(wx + 1), mosaicSize * TR * float(wy + 1));
} else {
v1 = vec2(mosaicSize * 1.5 * float(wx), mosaicSize * TR * float(wy + 1));
v2 = vec2(mosaicSize * 1.5 * float(wx + 1), mosaicSize * TR * float(wy));
}
} else {
if (wy/2 * 2 == wy) {
v1 = vec2(mosaicSize * 1.5 * float(wx), mosaicSize * TR * float(wy + 1));
v2 = vec2(mosaicSize * 1.5 * float(wx+1), mosaicSize * TR * float(wy));
} else {
v1 = vec2(mosaicSize * 1.5 * float(wx), mosaicSize * TR * float(wy));
v2 = vec2(mosaicSize * 1.5 * float(wx + 1), mosaicSize * 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 mid = texture2D(Texture, vn);
float a = atan((x - vn.x)/(y - vn.y));
vec2 area1 = vec2(vn.x, vn.y - mosaicSize * TR / 2.0);
vec2 area2 = vec2(vn.x + mosaicSize / 2.0, vn.y - mosaicSize * TR / 2.0);
vec2 area3 = vec2(vn.x + mosaicSize / 2.0, vn.y + mosaicSize * TR / 2.0);
vec2 area4 = vec2(vn.x, vn.y + mosaicSize * TR / 2.0);
vec2 area5 = vec2(vn.x - mosaicSize / 2.0, vn.y + mosaicSize * TR / 2.0);
vec2 area6 = vec2(vn.x - mosaicSize / 2.0, vn.y - mosaicSize * TR / 2.0);
if (a >= PI6 && a < PI6 * 3.0) {
vn = area1;
} else if (a >= PI6 * 3.0 && a < PI6 * 5.0) {
vn = area2;
} else if ((a >= PI6 * 5.0 && a <= PI6 * 6.0) || (a < -PI6 * 5.0 && a > -PI6 * 6.0)) {
vn = area3;
} else if (a < -PI6 * 3.0 && a >= -PI6 * 5.0) {
vn = area4;
} else if(a <= -PI6 && a> -PI6 * 3.0) {
vn = area5;
} else if (a > -PI6 && a < PI6) {
vn = area6;
}
vec4 color = texture2D(Texture, vn);
gl_FragColor = color;
}
复制代码