OpenGL (一)OpenGL ES 绘制基础
OpenGL (二)GLSurface 视频录制
OpenGL (三)滤镜filter 应用
OpenGL (四)贴纸和磨皮理论
扩散原理
回顾一下坐标系那张图
坐标.png片源着色器代码
varying highp vec2 aCoord;
uniform sampler2D vTexture;
uniform lowp float mixturePercent;
uniform highp float scalePercent;
void main() {
lowp vec4 textureColor = texture2D(vTexture, aCoord);
//gl_FragColor = textureColor;
highp vec2 textureCoordinateToUse = aCoord;
// 纹理中心点
highp vec2 center = vec2(0.5, 0.5);
// 当前要上颜色的点 与中心点的偏移
textureCoordinateToUse -= center;
//scalePercent: 放大参数
// 如果大于1,
textureCoordinateToUse = textureCoordinateToUse / scalePercent;
textureCoordinateToUse += center;
lowp vec4 textureColor2 = texture2D(vTexture, textureCoordinateToUse);
gl_FragColor = mix(textureColor, textureColor2, mixturePercent);
}
Java 端SoulFilter
package top.zcwfeng.opengl.filter;
import android.content.Context;
import android.opengl.GLES20;
import top.zcwfeng.opengl.R;
public
class SoulFilter extends AbstractFrameFilter{
private int mixturePercent;
private int scalePercent;
public SoulFilter(Context context) {
super(context, R.raw.base_vert,R.raw.soul_frag);
}
@Override
public void initGL(Context context, int vertexShaderId, int fragmentShaderId) {
super.initGL(context, vertexShaderId, fragmentShaderId);
mixturePercent = GLES20.glGetUniformLocation(program, "mixturePercent");
scalePercent = GLES20.glGetUniformLocation(program, "scalePercent");
}
float mix = 0.0f;// 透明度,越大越透明,但是android 里面alpha越小透明
float scale = 0.0f;//缩放,越来越大
@Override
public void beforeDraw(FilterContext filterContext) {
super.beforeDraw(filterContext);
GLES20.glUniform1f(mixturePercent,1.0f - mix);
GLES20.glUniform1f(scalePercent,1.0f + scale);
mix += 0.05f;
scale += 0.05f;
if(mix >= 1.0f) {
mix = 0.0f;
}
if(scale >= 1.0f){
scale = 0.0f;
}
}
}
A-B.png
带入一个实例点
0.5,0.5 --->中心点
0.5,0.3----> 找一个A点
A 点距离中新点y的距离 -0.2
-0.2 /2 = -0.1
0.5,0.4 -----> 找到一个B点
片源着色器,执行无数次,上一个点的颜色,画到当前这个点 A----> 着色到B
和大眼类似,盒子的底部颜色取色,画到原本有桌子的地方,效果感觉像贴了一层在桌子那部分,再加上透明度,就是这个效果
分屏思路
选取原图中的中心位置(0.25-0.75)进行绘制,大于0.5,则将当前绘制点Y坐标-0.25;否则加0.25即可。
上下分屏例子:
采点的时候0.25 下面,0.75 上面都抛弃
这个比较简单,看下着色器
precision mediump float;
varying vec2 aCoord;
uniform sampler2D vTexture;
void main() {
float y = aCoord.y;
if (y < 0.5){
y += 0.25;
} else {
y -= 0.25;
}
gl_FragColor = texture2D(vTexture, vec2(aCoord.x, y));
}
网友评论