【发布时间】:2014-08-28 17:57:39
【问题描述】:
我正在尝试使用 GLES20 在 GLSurfaceView 中实现混合效果。
视图具有颜色(红色)背景,在其上混合了蒙版纹理和具有 Alpha 通道的图像纹理。
这是一个示例蒙版和图像:
,
预期结果:
这是一个类似的问题,到目前为止它指导了我:OpenGL - mask with multiple textures
很遗憾,我无法获得类似的结果。以下是我的 onDraw() 方法的相关部分:
// Bind default FBO and use shader program
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glUseProgram(program);
// Set the vertex attributes
glVertexAttribPointer(texCoordHandle, 2, GL_FLOAT, false, 0, mTexVertices);
glEnableVertexAttribArray(texCoordHandle);
glVertexAttribPointer(posCoordHandle, 2, GL_FLOAT, false, 0, mPosVertices);
glEnableVertexAttribArray(posCoordHandle);
// Clear the buffer color - draw red color background
glClear(GL_COLOR_BUFFER_BIT);
// Apply transformation - irrelevant
glUniformMatrix4fv(mvpMatrixHandle, 1, false, matrix, 0);
// Bind the mask texture for drawing
glUniform1i(contentTextureHandle, 0);
glBindTexture(GL_TEXTURE_2D, textures[MASK_TEX]);
// Write alpha value 1.0 to white regions and 0.0 to black - don't change the RGB values
glBlendFuncSeparate(
GL_ZERO, // remove the source rgb colors
GL_ONE, // keep the destination rgb colors
GL_SRC_COLOR, // !! put high alpha (1.0) where image is white
GL_ZERO); // remove destination alpha
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
// Bind the content image
glBindTexture(GL_TEXTURE_2D, textures[CONTENT_TEX]);
// Change the blend function to write the regions with low alpha
glBlendFuncSeparate(
GL_ONE_MINUS_DST_ALPHA, // black regions (alpha 0): keep src rgb, white regions: remove src rgb
GL_DST_ALPHA, // black regions: remove dst rgb, white regions: keep dst rgb
GL_ONE_MINUS_DST_ALPHA, // black regions: keep src alpha, white regions: remove src alpha
GL_DST_ALPHA); // black regions: remove dst rgb, white regions: keep dst alpha
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
但是,结合这些混合函数的结果只会产生红色背景。
我已经尝试了两天的各种功能,但我认为上面的一个应该是对的。此外,在调试时,我尝试了glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);,但两个图像都显示在彼此之上(即纹理或 GL 设置没有问题):
我对上述混合函数的选择是基于funcSeparate后面的公式为:
Orgb = srgb *Srgb + drgb * Drgb
Oa = sa * Sa + da * Da
O:输出,s - 源,d - 目的地,其余参数来自 glBlendFuncSeparate(Srgb, Drgb, Sa, Da)
任何想法为什么纹理没有按预期混合或如何达到预期的结果?
已解决
我听从 Reto Koradi 的建议,将混合合并到我的片段着色器中:
"precision mediump float;\n" +
"uniform sampler2D tex_sampler;\n" +
"uniform sampler2D mask_sampler;\n" +
"varying vec2 v_texcoord;\n" +
"void main() {\n" +
" vec4 mask = texture2D(mask_sampler, v_texcoord);\n" +
" vec4 text = texture2D(tex_sampler, v_texcoord);\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";
请注意,我正在使用具有混合功能 .glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA) 的预乘位图。
我打算通过切换到具有相反颜色的蒙版来减少 (1.0 - mask.r) 部分(即在白色区域而不是黑色区域显示纹理)。
正确连接两个纹理(glActiveTexture 和 glUniform1i)有点棘手,但是网上有很多资源可以做到这一点。
【问题讨论】:
标签: android opengl-es-2.0 mask blending