正如我们所知,我们对OpenGL es 的操作也只是编写相应的着色器从而达到相应的图形或纹理。
而所谓的滤镜也只是通过对着色器的编写,也是对某个像素或坐标做特定的一些变换,从而达到滤镜的效果。
通过前面对顶点着色器、片段着色器、纹理的学习之后,也对OpenGL es有了一定的了解。
可通用的顶点着色器:
#version 300 es
//变换矩阵
uniform mat4 uMVPMatrix;
//顶点坐标
layout (location = 0) in vec4 aPosition;
//纹理坐标
layout (location = 1) in vec2 aTextureCoord;
//传给片段着色器
out vec2 vTextureCoord;
out vec4 vPosition;
void main() {
//对顶点做矩阵变换,从右边开始读
gl_Position = uMVPMatrix * aPosition;
vPosition= uMVPMatrix * aPosition;
vTextureCoord = aTextureCoord;
}
可通用的片段着色器:
#version 300 es
//片段着色器没有默认精度,必须声明
precision mediump float;
//纹理采样器
uniform sampler2D uTexture;
//接受顶点着色器传过来的坐标
in vec2 vTextureCoord;
in vec4 vPosition;
//输出的像素
out vec4 fragColor;
void main() {
//读取纹理的相应
vec4 color = texture(uTexture, vTextureCoord);
fragColor = color;
}
黑白滤镜:
原理挺简单只是对rgb三个通道的值进行运算
各种实现原理:
浮点算法: Gray = R * 0.3 + G * 0.59 + B * 0.11
整数算法: Gray = (R * 30 + G * 59 + B * 11) / 100
移位算法: Gray = (R * 76 + G * 151 + B * 28) >> 8
平均值法: Gray = (R + G + B) / 3;
仅取绿色: Gray = G
#version 300 es
//黑白滤镜
precision mediump float;
in vec2 vTextureCoord;
uniform sampler2D vTexture;
out vec4 fragColor;
void main() {
vec4 nColor = texture(vTexture,vTextureCoord);
//对rgb三个通道值取和除以3
float c=(nColor.r + nColor.g + nColor.b)/3.0;
fragColor = vec4(c, c, c, nColor.a);
}
4宫格滤镜:
原理是改变纹理坐标从而改变相应顶点的像素取值。
相当于改变后的坐标相对于原始坐标的一个映射,正如片段着色器就是决定某个顶点所取到的像素值。
[0,0.5]->[0,1]
[0.5,1]->[0,1]
#version 300 es
precision mediump float;
in vec2 vTextureCoord;
uniform sampler2D vTexture;
out vec4 fragColor;
void main() {
vec2 uv=vTextureCoord;
if(uv.x<=0.5){
uv.x = uv.x*2.0;
}else{
uv.x=(uv.x - 0.5)*2.0;
}
if (uv.y <= 0.5) {
uv.y = uv.y * 2.0;
} else {
uv.y = (uv.y - 0.5) * 2.0;
}
fragColor = texture(vTexture, uv);
}