2013-08-31 136 views
8

我正在学习OpenGL ES 2.0,我想创建一个应用程序以更好地了解它是如何工作的。 该应用程序有一套过滤器,用户可以应用在图像上(我知道,没有新的:P)。OpenGL ES 2.0中的图像和蒙版

一个该过滤器的采用两个图像和口罩,并通过面具融合两种图像显示他们(这里的图像,以便更好地解释,我想获得什么)

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

使用模板缓冲区或混合可能会更好吗?

+3

顺便说一句,你不必使用alpha('mask_color.a')通道作为掩码。你可以使用任何其他的'r','g','b'通道,这样你就可以通过使用不带alpha通道的遮罩纹理来节省GPU内存。 – keaukraine

+0

@MatterGoal可能是你可以回答这个问题,http://stackoverflow.com/questions/24486729/uiimage-masking-with-gesture –

回答

12

您可以在同一行敷面膜,而无需使用昂贵的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); 

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

+0

我是否使用多通道来创建模糊的蒙版?或者你建议使用相同的着色器创建模糊效果? – MatterGoal

+2

您可以通过执行多次(即5次)蒙版纹理拾取并对结果进行平均来使用相同着色器创建模糊。然后使用这个平均值而不是''vMask.r''。 –

+2

在这里你可以找到片段着色器中高斯模糊的实现:http://xissburg.com/faster-gaussian-blur-in-glsl/ –

1

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

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; 
} 

你可以看到,使用第三个纹理单元,只要做一个二进制测试上红色通道不是很有效,所以这将是更好的编码面具进入纹理1或2的alpha通道,但这应该让你开始。

+0

你是否建议在场景中应用任何特定设置以获得完美结果?对于一些“非线性”口罩,我得到了可怕的最终结果。 – MatterGoal

+2

OpenGL并未提供像素完美的结果,但您可以通过增加纹理的尺寸来提高质量。对于glTexParameteri(),使用GL_LINEAR作为MAG_FILTER和MIN_FILTER。缩小时,MIP_MAP只有帮助。 – ClayMontgomery