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\$
  • \$\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\$ – Kyle Hanson Sep 4 '14 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 '14 at 9:08
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\$
  • \$\begingroup\$ Any hint on how to do alpha masking and desaturation in a premultiplied Texture? \$\endgroup\$ – FrankMonza Sep 5 '14 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 '14 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 '14 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 '14 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 '14 at 11:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.