OpenGL ES 2.0中的图像和掩码

时间:2013-08-31 16:24:29

标签: opengl-es-2.0 shader

我正在学习OpenGL ES 2.0,我想创建一个应用程序来更好地理解它是如何工作的。 该应用程序有一组用户可以应用于图像的过滤器(我知道,没什么新的:P)。

这个过滤器中的一个采用两个图像和一个蒙版,它通过蒙版混合显示它们的两个图像(这里是一个图像,以更好地解释我想要获得的内容)

enter image description here

目前我真的很困惑,我不知道从哪里开始创造这种效果。 我无法理解我必须使用多个纹理和多个FrameBuffers,或者我可以使用单个着色器。

你有什么提示可以帮助我做这个项目吗?

编辑--------

我找到了这个解决方案,但是当我用作遮罩线而不是圆圈时,结果真的是“蹩脚”,特别是如果线条被旋转。

precision highp float;

varying vec4 FragColor;
varying highp vec2 TexCoordOut;

uniform sampler2D textureA;
uniform sampler2D textureB;
uniform sampler2D mask;

void main(void){
    vec4 mask_color = texture2D(mask, TexCoordOut);

    if (mask_color.a > 0.0){
        gl_FragColor =  texture2D(textureA, TexCoordOut);
    }else {
        gl_FragColor =  texture2D(textureB, TexCoordOut);
    }
}

使用Stencil缓冲区或混合可能更好吗?

2 个答案:

答案 0 :(得分:15)

您可以在不使用昂贵的if

的情况下在一行中应用蒙版
gl_FragColor = step( 0.5, vMask.r ) * vColor_1 + ( 1.0 - step( 0.5, vMask.r ) ) * vColor_2;

或者,最好只在两种颜色之间进行插值:

gl_FragColor = mix( vColor_1, vColor_2, vMask.r );

在这种情况下,可以平滑掩模(即,使用高斯模糊)以产生较少的混叠。与单值阈值相比,这将产生非常好的结果。

答案 1 :(得分:1)

不需要多个着色器或帧缓冲区,只需要多个纹理单元。只需使用3个纹理单元,这些纹理单元都由相同的纹理坐标索引,并使用蒙版纹理在其他两个纹理之间进行选择。片段着色器看起来像这样:

uniform sampler2D uTextureUnit_1;
uniform sampler2D uTextureUnit_2;
uniform sampler2D uTextureMask;
varying vec2 vTextureCoordinates;

void main()
{
    vec4 vColor_1 = texture2D(uTextureUnit_1, vTextureCoordinates);
    vec4 vColor_2 = texture2D(uTextureUnit_2, vTextureCoordinates);
    vec4 vMask = texture2D(uTextureMask, vTextureCoordinates);

    if (vMask.r > 0.5)
        gl_FragColor = vColor_1;
    else
        gl_FragColor = vColor_2;
}

你可以看到使用第三个纹理单元只是为了在Red通道上进行二进制测试效率不高,所以最好将掩码编码到纹理1或2的alpha通道中,但这应该得到你开始了。