我已经尝试使用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";
这是我的输出:
您可以在上方看到,位图图像仅以帧的白色或红色部分显示。但是我想用位图替换框架的黑色部分。或者我可以说我想在视频帧上屏蔽位图。我尝试了多个选项,例如制作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文件)。所以我想在视频的背景中放置位图。
在片段着色器中,您可以使用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