移动 前端 Python Android Java

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

2020-12-13  本文已影响0人  zcwfeng

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));
}
上一篇 下一篇

猜你喜欢

热点阅读