如何使用opengl在位图上屏蔽视频帧

问题描述 投票:0回答:1

我已经尝试使用OpenGL在位图上覆盖具有透明背景的视频帧。但是我没有得到预期的输出。这是我的着色器的代码:

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";

这是我的输出:

output

您可以在上方看到,位图图像仅以帧的白色或红色部分显示。但是我想用位图替换框架的黑色部分。或者我可以说我想在视频帧上屏蔽位图。我尝试了多个选项,例如制作2个和3个片段着色器进行叠加和使用glBlendFuncSeparate(GLES20.GL_ZERO,GLES20.GL_ONE,GLES20.GL_SRC_COLOR,GLES20.GL_ZERO),还使用glEnable(GLES20.GL_BLEND)glBlendFunc(GLES20.GL_SRC_ALPHA,GLES20.GL_ONE_MINUS_SRC_ALPHA)。但是我没有在这里找到成功。如果有人知道该问题的解决方案,那么让我知道对此有何建议。

注意,我的视频具有透明背景(.WEBM文件)。所以我想在视频的背景中放置位图。

java android bitmap opengl-es alpha-transparency
1个回答
0
投票

在片段着色器中,您可以使用discard关键字。此命令将导致片段的输出值被丢弃,并且颜色根本不会写入帧缓冲区。如果蒙版纹理的红色通道为0.0或1.0,则可以根据该值丢弃片段。例如:

discard

如果启用float mask = texture2D(sTexture, vTextureCoord).r; vec4 text = texture2D(oTexture, vTextureCoord); if (mask < 0.5) discard; gl_FragColor = text; 并设置以下混合功能

Blending

然后您必须绘制背景图像。确保glEnable(GLES20.GL_BLEND); glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); 被禁用。最后,纹理的Alpha通道必须由遮罩进行调制。例如:

Depth Test
© www.soinside.com 2019 - 2024. All rights reserved.