前言
通过修改Swift+OpenGLES 展示图片中的片元着色器代码,实现对图片的修改完成一些简单滤镜效果。
灰度滤镜
方法
通过对色值修改,然后使图片呈现灰度,对色值修改方案基本如下:
- 浮点算法: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;
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;
vec3 W = vec3(0.2125,0.7154,0.0721);
void main() {
vec4 color = texture2D(colorMap, varyTextCoord);
float gray = dot(color.rgb,W);
gl_FragColor = vec4(vec3(gray),color.a);
}
效果
颠倒图片
片元着色器
片元着色器修改代码如下:
precision highp float;
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;
void main() {
vec4 color = texture2D(colorMap, vec2(varyTextCoord.x,1.0 - varyTextCoord.y));
gl_FragColor = color;
}
效果
漩涡滤镜
片元着色器
片元着色器修改代码如下,每行都做了详细注释:
precision highp float;
//旋转角度
const float uD = 60.0;
//旋转半径比例
const float uR = 0.6;
varying lowp vec2 varyTextCoord;
uniform sampler2D colorMap;
void main() {
//纹理图片相对大小
ivec2 ires = ivec2(1,1);
//相对直径
float Res = float(ires.y);
vec2 st = varyTextCoord;
//旋转半径
float Radius = Res * uR;
//纹理相对坐标
vec2 xy = Res * st;
//以图片中心点为旋转中心,求与半径向量差目的是为了得到:1.长度是否在旋转范围内,2.角度加上旋转角度
vec2 dxy = xy - Res/2.0;
//长度
float r = length(dxy);
//抛物线递减因子
float attenValue = (1.0 - (r/Radius) * (r/Radius));
//旋转角度
float beta = atan(dxy.y,dxy.x) + radians(uD) * 2.0 *attenValue;
//在旋转范围内进行旋转、然后加上半径向量恢复到纹理相对坐标
if(r <= Radius) {
xy = Res/2.0 + r*vec2(cos(beta),sin(beta));
}
//重新拿到纹理坐标
st = xy/Res;
gl_FragColor = texture2D(colorMap,st);
}
其中vec2 dxy = xy - Res/2.0;
的目的已做注释,为更清晰理解见下图:
效果
正方形马赛克滤镜
片元着色器
片元着色器修改代码如下:
precision mediump float;
varying vec2 varyTextCoord;
uniform sampler2D colorMap;
//自定义图片大小,用于分割
const vec2 TexSize = vec2(500,500);
//分割大小即马赛克大小
const vec2 mosaicSize = vec2(20.0,20.0);
void main() {
vec2 textCoSize = vec2(varyTextCoord.x * TexSize.x, varyTextCoord.y * TexSize.y);
vec2 mosaicTex = vec2(floor(textCoSize.x/mosaicSize.x) *mosaicSize.x , floor(textCoSize.y/mosaicSize.y) * mosaicSize.y);
vec2 textC = vec2(mosaicTex.x / TexSize.x, mosaicTex.y / TexSize.y);
gl_FragColor = texture2D(colorMap,textC);
}