Применить альфа-маску к видео в OpenGL - PullRequest
2 голосов
/ 18 июня 2020

Я хочу применить к видео альфа-маску. Каждый кадр видео имеет информацию о цвете вверху и информацию об альфа-канале внизу. Вот так:

enter image description here

В моем случае я хочу, чтобы белые пиксели в альфа-изображении были прозрачными в основном изображении. У меня есть другая текстура, которая заполняет эти прозрачные пиксели.

Мне удалось сгенерировать только цветные изображения или только альфа-изображения, но я не смог применить альфа-канал к изображению. Я использую GLES20 в android.

Вот мой код, который показывает черный экран:

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)
    }
    """

Что я делаю не так?

PS Я новое в opengl.

1 Ответ

3 голосов
/ 18 июня 2020

Вычислить координату v изображения (uvs.y * 0.5 + 0.5) и маску (uvs.y * 0.5) в вершинном шейдере:

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)
}
...