在 OpenGL 中将 alpha 蒙版应用于视频
Apply alpha mask to video in OpenGL
我想对视频应用 alpha 蒙版。视频的每一帧在顶部都有颜色信息,在底部有 alpha 信息。像这样:
在我的例子中,我希望 alpha 图像中的白色像素在主图像中是透明的。我有另一个纹理填充那些透明像素。
我能够生成唯一的彩色图像或仅生成 alpha 图像,但无法将 alpha 应用于图像。我在 android.
中使用 GLES20
这是我的黑屏代码:
private val vidVertexShaderCode =
"""
precision highp float;
attribute vec3 vertexPosition;
attribute vec4 uvs;
varying vec2 varUvs;
varying vec2 varMaskUvs;
uniform mat4 texMatrix;
uniform mat4 mvp;
void main()
{
varUvs = (texMatrix * vec4(uvs.x, uvs.y, 0, 1.0)).xy;
varMaskUvs = (texMatrix * vec4(uvs.x, uvs.y * 0.5, 0.1, 1.0)).xy;
gl_Position = mvp * vec4(vertexPosition, 1.0);
}
"""
private val vidFragmentShaderCode =
"""
#extension GL_OES_EGL_image_external : require
precision mediump float;
varying vec2 varUvs;
varying vec2 varMaskUvs;
uniform samplerExternalOES texSampler;
void main()
{
vec2 m_uv = vec2(varMaskUvs.x, varMaskUvs.y);
vec4 mask = texture2D(texSampler, m_uv);
vec2 c_uv = vec2(varUvs.x, varUvs.y * 0.5);
vec4 color = texture2D(texSampler, c_uv);
gl_FragColor = vec4(color.rgb, color.a * mask.r)
}
"""
我做错了什么?
P.S。我是 opengl 的新手。
在顶点着色器中计算图像 (uvs.y * 0.5 + 0.5
) 和遮罩 (uvs.y * 0.5
) 的 v 坐标:
precision highp float;
attribute vec3 vertexPosition;
attribute vec4 uvs;
varying vec2 varUvs;
varying vec2 varMaskUvs;
uniform mat4 texMatrix;
uniform mat4 mvp;
void main()
{
varUvs = (texMatrix * vec4(uvs.x, uvs.y * 0.5 + 0.5, 0, 1.0)).xy;
varMaskUvs = (texMatrix * vec4(uvs.x, uvs.y * 0.5, 0.0, 1.0)).xy;
gl_Position = mvp * vec4(vertexPosition, 1.0);
}
您不需要在片段着色器中进行任何进一步的转换:
#extension GL_OES_EGL_image_external : require
precision mediump float;
varying vec2 varUvs;
varying vec2 varMaskUvs;
uniform samplerExternalOES texSampler;
void main()
{
vec4 mask = texture2D(texSampler, varMaskUvs);
vec4 color = texture2D(texSampler, varUvs);
gl_FragColor = vec4(color.rgb, color.a * mask.r)
}
我想对视频应用 alpha 蒙版。视频的每一帧在顶部都有颜色信息,在底部有 alpha 信息。像这样:
在我的例子中,我希望 alpha 图像中的白色像素在主图像中是透明的。我有另一个纹理填充那些透明像素。
我能够生成唯一的彩色图像或仅生成 alpha 图像,但无法将 alpha 应用于图像。我在 android.
中使用 GLES20这是我的黑屏代码:
private val vidVertexShaderCode =
"""
precision highp float;
attribute vec3 vertexPosition;
attribute vec4 uvs;
varying vec2 varUvs;
varying vec2 varMaskUvs;
uniform mat4 texMatrix;
uniform mat4 mvp;
void main()
{
varUvs = (texMatrix * vec4(uvs.x, uvs.y, 0, 1.0)).xy;
varMaskUvs = (texMatrix * vec4(uvs.x, uvs.y * 0.5, 0.1, 1.0)).xy;
gl_Position = mvp * vec4(vertexPosition, 1.0);
}
"""
private val vidFragmentShaderCode =
"""
#extension GL_OES_EGL_image_external : require
precision mediump float;
varying vec2 varUvs;
varying vec2 varMaskUvs;
uniform samplerExternalOES texSampler;
void main()
{
vec2 m_uv = vec2(varMaskUvs.x, varMaskUvs.y);
vec4 mask = texture2D(texSampler, m_uv);
vec2 c_uv = vec2(varUvs.x, varUvs.y * 0.5);
vec4 color = texture2D(texSampler, c_uv);
gl_FragColor = vec4(color.rgb, color.a * mask.r)
}
"""
我做错了什么?
P.S。我是 opengl 的新手。
在顶点着色器中计算图像 (uvs.y * 0.5 + 0.5
) 和遮罩 (uvs.y * 0.5
) 的 v 坐标:
precision highp float;
attribute vec3 vertexPosition;
attribute vec4 uvs;
varying vec2 varUvs;
varying vec2 varMaskUvs;
uniform mat4 texMatrix;
uniform mat4 mvp;
void main()
{
varUvs = (texMatrix * vec4(uvs.x, uvs.y * 0.5 + 0.5, 0, 1.0)).xy;
varMaskUvs = (texMatrix * vec4(uvs.x, uvs.y * 0.5, 0.0, 1.0)).xy;
gl_Position = mvp * vec4(vertexPosition, 1.0);
}
您不需要在片段着色器中进行任何进一步的转换:
#extension GL_OES_EGL_image_external : require
precision mediump float;
varying vec2 varUvs;
varying vec2 varMaskUvs;
uniform samplerExternalOES texSampler;
void main()
{
vec4 mask = texture2D(texSampler, varMaskUvs);
vec4 color = texture2D(texSampler, varUvs);
gl_FragColor = vec4(color.rgb, color.a * mask.r)
}