3
\$\begingroup\$

I have a very large texture i am using as background and i want to apply a filter to a small part of it, the "small part" is defined by the alpha layer of another texture i have (which is still RGB8888), i am not sure what's the best approach to do this. I'd like to keep the same (very simple) shader i am already using for other sprites, which is similar to the basic one, i.e.:

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

So, i have some questions

  • How can i apply my filter only to "masked" region and avoid drawing others?
  • Do i have any performance loss if i draw the big texture again once loaded to just apply it to a small portion of the screen?
  • Can i map a second texture to the shader and use something like "if uTexture2 != null" -> apply as mask? Will this give me any performance gain compared to using a second shader?
  • Both textures are premultiplied, how should i handle alpha masking?

What id like to do is something like this (original, mask, result):

Base Texture Alpha Mask Result

My environment is Android 4.0, im using GLES20.

\$\endgroup\$
2
  • \$\begingroup\$ You're not likely to incur any significant performance hits for using two textures in a single shader. It's probably best to just write a second shader that does the desaturation masking. For alpha masking, you just should make sure that the desaturate function doesn't touch the original alpha component. That way you retain the pre-multiplied alpha in your source texture. If performance is really a concern you should just profile it and see if there's any difference, which there isn't likely to be. \$\endgroup\$ Sep 4, 2014 at 22:00
  • \$\begingroup\$ Thanks! So drawing the big texture again just to redraw a small part of it (since alpha masking is small) will not be a huge performance penalty? \$\endgroup\$
    – FrankMonza
    Sep 5, 2014 at 9:08

1 Answer 1

3
\$\begingroup\$

I'd go for a second shader that accepts two textures and does the desaturation. Performance loss will be minimal.

uniform sampler2D tex;
uniform sampler2D texA;

void main()
{
    vec4 texelColor = texture2D(tex, gl_TexCoord[0].xy);
    vec4 maskColor = texture2D(texA, gl_TexCoord[1].xy);

    vec4 desatColor = texelColor * vec4(0.3, 0.59, 0.11, 1.0); // Weightened greyscaling
    float luminance = desatColor.r + desatColor.g + desatColor.b;
    desatColor = vec4(luminance, luminance, luminance, texelColor.a);
    gl_FragColor = mix(texelColor, desatColor, maskColor.a);
}
\$\endgroup\$
5
  • \$\begingroup\$ Any hint on how to do alpha masking and desaturation in a premultiplied Texture? \$\endgroup\$
    – FrankMonza
    Sep 5, 2014 at 10:16
  • \$\begingroup\$ What do you mean by Premultiplied texture? I got an impression you have RGB background and A mask. \$\endgroup\$
    – Kromster
    Sep 5, 2014 at 10:30
  • \$\begingroup\$ I have an RGB background and a RGBA (alpha premultiplied) texture i need to use as a mask, this is because that mask is also a sprite i use elsewhere drawing it normally, anyway marking your answer as correct since it puts me in the correct path (and thanks btw!) \$\endgroup\$
    – FrankMonza
    Sep 5, 2014 at 11:45
  • 1
    \$\begingroup\$ If you are using just Alpha from the second texture, it does not matter if it is premultiplied or not. \$\endgroup\$
    – Kromster
    Sep 5, 2014 at 11:48
  • \$\begingroup\$ Great! Thanks a lot! I will also "up" the answer as soon as i have 15 points :) \$\endgroup\$
    – FrankMonza
    Sep 5, 2014 at 11:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .