简体   繁体   中英

How to mask video frame over bitmap using opengl

I have tried to overlay video frame with transparent background over bitmap using OpenGL . But i didn't get expected output. Here is my shader's code:

VertexShader :

"uniform mat4 uMVPMatrix;\n" +
"uniform mat4 uSTMatrix;\n" +
"attribute vec4 aPosition;\n" +
"attribute vec4 aTextureCoord;\n" +
"varying vec2 vTextureCoord;\n" +
"void main() {\n" +
"  gl_Position = uMVPMatrix * aPosition;\n" +
"  vTextureCoord = (uSTMatrix * aTextureCoord).xy;\n" +
"}\n";

FragmentShader :

"#extension GL_OES_EGL_image_external : require\n" +
"precision mediump float;\n" +      // highp here doesn't seem to matter
"varying vec2 vTextureCoord;\n" +
"uniform sampler2D sTexture;\n" +
"uniform samplerExternalOES oTexture;\n" +
"void main() {\n" +
"  vec4 mask = texture2D(sTexture, vTextureCoord);\n" +
"  vec4 text = texture2D(oTexture, vTextureCoord);\n" +
"  gl_FragColor = vec4(text.r * (1.0 - mask.r), text.g * (1.0 - mask.r), text.b * (1.0 - mask.r), text.a * (1.0 - mask.r));\n" +
"}\n";

And here is my output:

输出

You can see above, bitmap image shown only in white or red part of frame. But i want to replace black part of frame with bitmap. Or i can say i want to mask bitmap over video frame. I have tried multiple options like making 2 and three fragment-shaders for overlaying and using glBlendFuncSeparate(GLES20.GL_ZERO,GLES20.GL_ONE,GLES20.GL_SRC_COLOR,GLES20.GL_ZERO) and also using glEnable(GLES20.GL_BLEND) and glBlendFunc(GLES20.GL_SRC_ALPHA,GLES20.GL_ONE_MINUS_SRC_ALPHA) . But i didn't find success here. If anyone know what is solution of this problem than let me know what is suggestion for this.

NOTE that I have video with transparent background(.WEBM file). So i want to place bitmap in the video's background.

In a fragment shader you can use the discard keyword. This command causes the fragment's output values to be discarded and that the color is not written to the framebuffer at all.
It the red color channel of the mask texture is either 0.0 or 1.0 then fragments can be discarded dependent on that value. eg:

float mask = texture2D(sTexture, vTextureCoord).r;
vec4  text = texture2D(oTexture, vTextureCoord);

if (mask < 0.5)
    discard;

gl_FragColor = text; 

If you enable Blending and set the following blend function

glEnable(GLES20.GL_BLEND);
glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);

then you've to draw the background image before. Ensure that the Depth Test is disabled. Finally the alpha channel of the texture has to be modulated by the mask. eg:

float mask = texture2D(sTexture, vTextureCoord).r;
vec4  text = texture2D(oTexture, vTextureCoord);

gl_FragColor = vec4(text.rgb, text.a * mask); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM