使用OpenGL 2中的掩码去饱和纹理

时间:2014-09-04 12:19:12

标签: android opengl-es opengl-es-2.0 mask

我有一个非常大的纹理,我用作背景,我想将滤镜应用到它的一小部分,“小部分”是由我拥有的另一个纹理的alpha层定义(仍然是RGB8888) ,我不确定这样做的最佳方法是什么。我想保留我已经用于其他精灵的相同(非常简单)着色器,这类似于基本精灵,即:

precision mediump float;
uniform sampler2D uTexture;
varying vec2 vTexPos;
void main() {
  gl_FragColor = texture2D(uTexture, vTexPos);
}

所以,我有一些问题

  • 如何将我的过滤器仅应用于“蒙面”区域并避免绘制其他区域?
  • 如果我加载后再次绘制大纹理,只是将它应用到屏幕的一小部分,我是否会有任何性能损失?
  • 我可以将第二个纹理映射到着色器并使用类似“if uTexture2!= null” - >申请作为面具?与使用第二个着色器相比,这会给我带来任何性能提升吗?
  • 两种纹理都是预乘的,我应该如何处理alpha遮罩?

喜欢做什么就是这样(原创,面具,结果):

Base Texture Alpha Mask Result

我的环境是Android 4.0,我正在使用GLES20。

1 个答案:

答案 0 :(得分:1)

您需要使用额外的蒙版纹理采样器的颜色测试,以及基于条件的一些去饱和过滤器。

此片段着色器应该可以工作:

precision mediump float;
uniform sampler2D uTexture;
uniform sampler2D uMask;
varying vec2 vTexPos;

void main() {
    vec4 mask = texture2D(uMask, vTexPos);
    if(mask.r < 0.9) { // black mask
        gl_FragColor = texture2D(uTexture, vTexPos);
    } else { // white mask
        vec4 texelColor = texture2D(uTexture, vTexPos); // original color
        vec4 scaledColor = texelColor * vec4(0.3, 0.59, 0.11, 1.0); // weights calculation
        float luminance = scaledColor.r + scaledColor.g + scaledColor.b; // greyscale
        gl_FragColor = vec4(luminance, luminance, luminance, texelColor.a); // final color with original alpha value
    }
}

去饱和代码来自这篇伟大的文章: http://franzzle.wordpress.com/2013/03/25/use-a-opengl-es-2-0-shader-to-show-a-desaturated-sprite-in-cocos2d-2-0/