Как замаскировать видеокадр поверх растрового изображения с помощью opengl - PullRequest
0 голосов
/ 28 сентября 2019

Я попытался наложить видеокадр с прозрачным фоном поверх растрового изображения, используя 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 и трех фрагментных шейдеров для наложения и использование 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).Поэтому я хочу разместить растровое изображение на заднем плане видео.

1 Ответ

0 голосов
/ 28 сентября 2019

В фрагментном шейдере вы можете использовать ключевое слово discard.Эта команда приводит к тому, что выходные значения фрагмента отбрасываются и цвет вообще не записывается в кадровый буфер.
Если канал красного цвета текстуры маски равен либо 0,0, либо 1,0, тогда фрагменты можно отбрасывать в зависимости от этого значения.Например:

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

if (mask < 0.5)
    discard;

gl_FragColor = text; 

Если вы включите Смешивание и установите следующую функцию смешивания

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

, то вы должны нарисовать фоновое изображение раньше.Убедитесь, что Проверка глубины отключена.Наконец, альфа-канал текстуры должен модулироваться маской.например:

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

gl_FragColor = vec4(text.rgb, text.a * mask); 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...