美文网首页 移动 前端 Python Android Java
OpenGL(五)灵魂出窍和分屏效果

OpenGL(五)灵魂出窍和分屏效果

作者: zcwfeng | 来源:发表于2020-12-13 00:29 被阅读0次

    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));
    }
    

    相关文章

      网友评论

        本文标题:OpenGL(五)灵魂出窍和分屏效果

        本文链接:https://www.haomeiwen.com/subject/kmedgktx.html